Javascript 动态渲染 React 组件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26518629/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-22 22:59:17  来源:igfitidea点击:

Dynamically Rendering a React component

javascriptreactjs

提问by eriklharper

In React JSX it does not appear to be possible to do something like this:

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

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

I get a parse error: Unexpected token {. Is this not something React can handle?

我收到一个解析错误:意外的令牌 {。这不是 React 可以处理的吗?

I'm designing this component so that under the hood, the values stored in this.props.component.slugwill contain valid HTML elements (h1, p, etc.). Is there any way to make this work?

我正在设计这个组件,以便在引擎盖下,存储在其中的值this.props.component.slug将包含有效的 HTML 元素(h1、p 等)。有什么办法可以使这项工作?

回答by nilgun

You should not put component slug in curly braces:

您不应该将组件 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);

Here is a working fiddle: http://jsfiddle.net/kb3gN/6668/

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

Also, you can find JSX Compiler helpful for debugging these kind of errors: http://facebook.github.io/react/jsx-compiler.html

此外,您可以找到有助于调试此类错误的 JSX 编译器:http: //facebook.github.io/react/jsx-compiler.html

回答by Jan Klimo

As nilgun previously pointed out, the component slug should not be wrapped in curly braces.

正如 nilgun 之前指出的那样,组件 slug 不应包裹在花括号中。

If you decide to store it in a variable, make sure it starts with a capital letter.

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

Here is an example:

下面是一个例子:

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'));

Here's a working fiddle: https://jsfiddle.net/janklimo/yc3qcd0u/

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

回答by Gudlaugur Egilsson

If your intention is to inject the actual component rendered, you can do something like this, which is very convenient for testing, or whatever reason you would want to dynamically inject components to render.

如果你的意图是注入实际渲染的组件,你可以做这样的事情,这对于测试非常方便,或者你想动态注入组件来渲染。

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

回答by fankt

Edit: Maybe you forgot to add /** @jsx React.DOM */at the beginning of js?

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

You can use React.DOMthough:

你可以使用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

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

I am not a React expert, but I think every component should be construct with a specific tag at the beginning. So it could present a clear purpose itself.

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

回答by Juanma Menendez

The solution for me was to assign the imported Component to a variable(with CapitalCase) and then render the variable between

我的解决方案是将导入的组件分配给一个变量(使用大写字母),然后在之间呈现变量

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

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

        // your custom logic to assing the variable goes here...
       const TagName = this.components.foo;

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