【问题标题】:Dynamically Rendering a React component动态渲染 React 组件
【发布时间】:2014-12-18 13:30:16
【问题描述】:

在 React JSX 中似乎不可能做这样的事情:

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

我得到一个解析错误:Unexpected token {.这不是反应吗 可以处理吗?

我正在设计这个组件,以便在后台,this.props.component.slug 中存储的值将包含有效的 HTML 元素(h1、p 等)。有什么办法可以做到吗?

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    您不应该将组件 slug 放在花括号中:

    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 编译器有助于调试这些类型的错误: http://facebook.github.io/react/jsx-compiler.html

    【讨论】:

    • 我刚刚解决的一个问题是,您必须提供一个点才能识别任何其他变量,即 var page; &lt;page&gt;&lt;/page&gt; 不起作用而 var page = { component: component }; &lt;page.component&gt;&lt;/page.component&gt; 起作用
    • React 将变量视为自定义元素,如果它们是大写的或有点符号的,否则是 HTML 元素。 IE。 也可以使用
    • 必须将 React.DOM.div 替换为 'div' 才能正常工作
    • 请记住,您的变量应该包含组件本身,而而不是只是组件的名称作为字符串.
    【解决方案2】:

    正如 nilgun 之前指出的,组件 slug 不应该用花括号包裹。

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

    这是一个例子:

    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/

    【讨论】:

    • 你摇滚!!变量名应以大写字母开头。这很奇怪,但就是这样。
    【解决方案3】:

    如果您的意图是注入实际渲染的组件,您可以这样做,这对于测试非常方便,或者您希望动态注入组件进行渲染的任何原因。

    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"));
    });
    

    【讨论】:

      【解决方案4】:

      编辑:可能你忘了在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 专家,但我认为每个组件都应该在开始时使用特定的标签来构造。所以它本身可以提出一个明确的目的。

      【讨论】:

        【解决方案5】:

        我的解决方案是将导入的组件分配给一个变量(使用 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;
        

        【讨论】:

          猜你喜欢
          • 2020-02-28
          • 1970-01-01
          • 1970-01-01
          • 2022-01-25
          • 1970-01-01
          • 2015-02-10
          • 2018-12-21
          • 2020-07-12
          • 1970-01-01
          相关资源
          最近更新 更多