React / JSXdynamic组件名称

我想dynamic呈现组件的types。

例如:

var type = "Example"; var ComponentName = type + "Component"; return <ComponentName />; // Returns <examplecomponent /> instead of <ExampleComponent /> 

我尝试了这里提出的解决schemeReact / JSXdynamic组件名称

这在编译时给我一个错误(使用browserify for gulp)。 它期望我使用数组语法的XML。

我可以通过为每个组件创build一个方法来解决这个问题:

 newExampleComponent() { return <ExampleComponent />; } newComponent(type) { return this["new" + type + "Component"](); } 

但是,这意味着我创build每个组件的新方法。 这个问题必须有一个更优雅的解决scheme。

我非常乐于提供build议。

<MyComponent />编译为React.createElement(MyComponent, {}) ,它需要一个string(HTML标记)或一个函数(ReactClass)作为第一个参数。

您可以将组件类存储在名称以大写字母开头的variables中。 查看HTML标记与React组件 。

 var MyComponent = Components[type + "Component"]; return <MyComponent />; 

编译

 var MyComponent = Components[type + "Component"]; return React.createElement(MyComponent, {}); 

有关于如何处理此类情况的官方文档可在此处获得: https : //facebook.github.io/react/docs/jsx-in-depth.html#choosing-the-type-at-runtime

基本上它说:

错误:

 import React from 'react'; import { PhotoStory, VideoStory } from './stories'; const components = { photo: PhotoStory, video: VideoStory }; function Story(props) { // Wrong! JSX type can't be an expression. return <components[props.storyType] story={props.story} />; } 

正确:

 import React from 'react'; import { PhotoStory, VideoStory } from './stories'; const components = { photo: PhotoStory, video: VideoStory }; function Story(props) { // Correct! JSX type can be a capitalized variable. const SpecificStory = components[props.storyType]; return <SpecificStory story={props.story} />; } 

我想出了一个新的解决scheme。 请注意,我正在使用ES6模块,所以我需要这个类。 你也可以定义一个新的React类。

 var components = { example: React.createFactory( require('./ExampleComponent') ) }; var type = "example"; newComponent() { return components[type]({ attribute: "value" }); } 

如果你的组件是全球性的,你可以简单地做:

 var nameOfComponent = "SomeComponent"; React.createElement(window[nameOfComponent], {}); 

对于一个包装器组件,一个简单的解决scheme就是直接使用React.createElement (使用ES6)。

 import RaisedButton from 'mui/RaisedButton' import FlatButton from 'mui/FlatButton' import IconButton from 'mui/IconButton' class Button extends React.Component { render() { const { type, ...props } = this.props let button = null switch (type) { case 'flat': button = FlatButton break case 'icon': button = IconButton break default: button = RaisedButton break } return ( React.createElement(button, { ...props, disableTouchRipple: true, disableFocusRipple: true }) ) } } 

编辑:其他答案更好,看评论。

我这样解决了同样的问题:

 ... render : function () { var componentToRender = 'component1Name'; var componentLookup = { component1Name : (<Component1 />), component2Name : (<Component2 />), ... }; return (<div> {componentLookup[componentToRender]} </div>); } ... 

暂停我们希望通过dynamic组件加载来访问各种视图。下面的代码给出了一个工作示例,说明如何使用从url的searchstringparsing的string来完成此操作。

让我们假设我们想要访问一个页面'snozberrys'有两个独特的视图使用这些URLpath:

 'http://localhost:3000/snozberrys?aComponent' 

 'http://localhost:3000/snozberrys?bComponent' 

我们定义我们的视图的控制器是这样的:

 import React, { Component } from 'react'; import ReactDOM from 'react-dom' import { BrowserRouter as Router, Route } from 'react-router-dom' import AComponent from './AComponent.js'; import CoBComponent sole from './BComponent.js'; const views = { aComponent: <AComponent />, console: <BComponent /> } const View = (props) => { let name = props.location.search.substr(1); let view = views[name]; if(view == null) throw "View '" + name + "' is undefined"; return view; } class ViewManager extends Component { render() { return ( <Router> <div> <Route path='/' component={View}/> </div> </Router> ); } } export default ViewManager ReactDOM.render(<ViewManager />, document.getElementById('root')); 

我用了一个不同的方法,因为我们总是知道我们的实际组件,所以我想应用开关情况。 在我的情况下,组件总数也是7-8。

 getSubComponent(name) { let customProps = { "prop1" :"", "prop2":"", "prop3":"", "prop4":"" } switch (name) { case "Component1": return <Component1 {...this.props} {...customProps} /> case "Component2": return <Component2 {...this.props} {...customProps} /> case "component3": return <component3 {...this.props} {...customProps} /> } }