如何在渲染中使用动态react类元素?

时间:2015-12-09 20:45:19

标签: react-jsx

我理解这个问题不明确,所以说明会有所帮助。

所以,我有一些反应组件,如

var LandingPage = React.createClass({
    render: function() {
        return <div>
            This is the landing page.
        </div>
    }
})

之类的其他组件
var FirstContent = React.createClass({
        render: function() {
            return <div>
                This is first content page
            </div>
        }
    })

现在我有一个控制器,通过在props中传递一个值来决定我需要渲染哪一个 - 像这样 -

var Contoller = React.createClass({
        render: function() {
            var inside = "";
            if (this.props.pageName == "LandingPage") {
                inside = <LandingPage />;
            } else if (this.props.pageName == "FirstContent") {
                inside = <FirstContent />;
            }
            return <div>
                {inside}
            </div>;
        }
    })

现在,我想做一些事情,直接使用标签内的this.props.pageName,这样我就不必每次都写一些新的替代内容。应该是这样的 -

var Contoller = React.createClass({
        render: function() {
            return <div>
                <"this.props.pageName" /> //comment - <LandingPage /> if this.props.pageName = "LandingPage"
            </div>;
        }
    })

2 个答案:

答案 0 :(得分:2)

pageName到实际组件的映射必须存在某处,因为除了默认的HTML元素(如div)之外,React需要类对象引用来呈现零件。字符串不会。

您如何管理此地图取决于您,但我使用了下面的对象。

更复杂的是JSX编译步骤,它不适用于动态内容。您必须在Controller中使用实际的JS调用才能使其正常工作。

以下a codepen证明了这一点。

class LandingPage extends React.Component {
  render() {
    return <div> This is the landing page. </div>;
  }
}

class FirstContent extends React.Component {
  render() {
    return <div> This is the first content page. </div>;
  }
}

const map = {
  LandingPage: LandingPage,
  FirstContent: FirstContent
};

class Controller extends React.Component {
  render() {
    return React.createElement(map[this.props.pageName]);
  }
}

React.render(<Controller pageName={'LandingPage'} />, document.body);

所有这一切,我认为你正在构建路由器。您可以在memory mode中使用react-router来执行路由,而无需使用URL。在这里滚动你自己的设置可能比它的价值更多。

答案 1 :(得分:1)

The map does exist in the example by Tyrsius: you can use window[this.props.pageName]. Though it's better not to expose your components to the window object. And it may not work at all if you're using CommonJS for your React components.

If you don't need to build a name of several parts, why don't you just pass the component itself instead of a string? Either as a property or, better, as a child:

class Controller extends React.Component {
  render() {
    return <div>{this.props.children}</div>;
  }
}

React.render(<Controller><FirstContent/></Controller>, document.body);