动态渲染 React 组件

在 React JSX 中,似乎不可能做到这一点:

render: function() {
return (
<{this.props.component.slug} className='text'>
{this.props.component.value}
</{this.props.component.slug}>
);
}

我得到一个解析错误: 意外的令牌{ 可以处理?

我正在设计这个组件,以便在底层,存储在 this.props.component.slug中的值将包含有效的 HTML 元素(h1、 p 等)。有办法解决吗?

87126 次浏览

编辑 : 也许您忘记在 js 的开头添加 /** @jsx React.DOM */了?

不过,你可以使用 React.DOM:

render: function() {
return React.DOM[this.props.component.slug](null, this.props.component.value);
}

Http://jsbin.com/rerehutena/2/edit?html,js,output

我不是 React 专家,但我认为每个组件都应该在开始时用特定的标签来构建。所以它本身就有明确的目的。

你不应该把组件蛞蝓放在花括号里:

var Hello = React.createClass({
render: function() {
return <this.props.component.slug className='text'>
{this.props.component.value}
</this.props.component.slug>;
}
});


React.renderComponent(<Hello component=\{\{slug:React.DOM.div, value:'This is my header'}} />, document.body);

这是一个工作小提琴: http://jsfiddle.net/kb3gN/6668/

此外,您可以发现 JSX Compiler 对于调试这类错误很有帮助: Http://facebook.github.io/react/jsx-compiler.html

正如 Nilgun 先前指出的那样,组件弹头不应该被卷曲的支撑所包裹。

如果您决定将它存储在一个变量中,请确保它以大写字母开头。

这里有一个例子:

var Home = React.createClass({
render: function() {
return (
<div>
<h3>This is an input</h3>
<CustomComponent inputType="input" />
<h3>This is a text area</h3>
<CustomComponent inputType="textarea" />
</div>
);
}
});


var CustomComponent = React.createClass({
render: function() {
// make sure this var starts with a capital letter
var InputType = this.props.inputType;
return <InputType />;
}
});


React.render(<Home />, document.getElementById('container'));

这里有一个工作小提琴: https://jsfiddle.net/janklimo/yc3qcd0u/

如果您的意图是注入所呈现的实际组件,您可以执行类似的操作,这对于测试非常方便,或者您想要动态注入组件以呈现的任何原因。

var MyComponentF=function(ChildComponent){
var MyComponent = React.createClass({
getInitialState: function () {
return {
};
},
componentDidMount: function () {
},
render: function () {
return (
<div className="MyComponent">
<ChildComponent></ChildComponent>
</div>
);
}
});
return MyComponent;
};


var OtherComponentF=function(){
var OtherComponent = React.createClass({
getInitialState: function () {
return {
};
},
componentDidMount: function () {
},
render: function () {
return (
<div className="OtherComponent">
OtherComponent
</div>
);
}
});
return OtherComponent;
};


var AnotherComponentF=function(){
var AnotherComponent = React.createClass({
getInitialState: function () {
return {
};
},
componentDidMount: function () {
},
render: function () {
return (
<div className="AnotherComponent">
AnotherComponent
</div>
);
}
});
return AnotherComponent;
};


$(document).ready(function () {
var appComponent = MyComponentF(OtherComponentF());


// OR
var appComponent = MyComponentF(AnotherComponentF());


// Results will differ depending on injected component.


ReactDOM.render(React.createElement(appComponent), document.getElementById("app-container"));
});

我的解决方案是将导入的 Component 分配给一个变量(使用 CapitalCase) ,然后呈现该变量。

例如:

import React, { Component } from 'react';
import FooComponent from './foo-component';
import BarComponent from './bar-component';


class MyComponent extends Component {
components = {
foo: FooComponent,
bar: BarComponent
};


//this is the most important step
const TagName = this.components.foo;


render() {
return <TagName />
}
}
export default MyComponent;