我试图根据组件的类型动态呈现组件。

例如:

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

我尝试了这里提出的React/JSX动态组件名称的解决方案

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

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

newExampleComponent() {
    return <ExampleComponent />;
}

newComponent(type) {
    return this["new" + type + "Component"]();
}

但这意味着我创建的每个组件都有一个新方法。这个问题一定有更优雅的解决办法。

我很愿意接受建议。

编辑: 正如gmfvpereira最近指出的,有一个官方文档条目: https://reactjs.org/docs/jsx-in-depth.html#choosing-the-type-at-runtime


当前回答

对于包装器组件,一个简单的解决方案就是使用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 })
    )
  }
}

其他回答

假设你能够像这样从组件中导出*…

// src/components/index.js

export * from './Home'
export * from './Settings'
export * from './SiteList'

然后你可以重新导入*到一个新的comps对象中,然后它可以用来访问你的模块。

// src/components/DynamicLoader.js

import React from 'react'
import * as comps from 'components'

export default function ({component, defaultProps}) {
  const DynamicComponent = comps[component]

  return <DynamicComponent {...defaultProps} />
}

只需传入一个字符串值,该值标识您想要绘制的组件,以及需要绘制组件的位置。

<DynamicLoader component='Home' defaultProps={someProps} />

我使用了一点不同的方法,因为我们总是知道我们的实际组件,所以我认为应用开关情况。 另外,在我的案例中,组件总数在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} />

    }
  }

假设我们有一个旗帜,与国家或道具没有什么不同:

import ComponentOne from './ComponentOne';
import ComponentTwo from './ComponentTwo';

~~~

const Compo = flag ? ComponentOne : ComponentTwo;

~~~

<Compo someProp={someValue} />

用Compo标记填充ComponentOne或ComponentTwo中的一个,然后Compo可以像React组件一样工作。

如果你的组件是全局的,你可以简单地这样做: var nameOfComponent = " someecomponent "; 反应。createElement(窗口(nameOfComponent), {});

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

我用这种方法解决了同样的问题:

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