Class 从字符串创建React类的实例

Class 从字符串创建React类的实例,class,dynamic,reactjs,instance,Class,Dynamic,Reactjs,Instance,我有一个字符串,其中包含类的名称(来自json文件)。这个字符串告诉我的Template类数据使用哪个布局/模板(也在json中)。问题是我的布局没有显示 Home.jsx: //a template or layout. var Home = React.createClass({ render () { return ( <div>Home layout</div> ) } }); 有什么想法吗,我怎么解决这个问题?我肯定这不是简单的

我有一个字符串,其中包含类的名称(来自json文件)。这个字符串告诉我的Template类数据使用哪个布局/模板(也在json中)。问题是我的布局没有显示

Home.jsx:

//a template or layout.
var Home = React.createClass({
  render () {
    return (
    <div>Home layout</div>
    )
  }
});
有什么想法吗,我怎么解决这个问题?我肯定这不是简单的修复,就是我在做傻事。我们将不胜感激。如果已经有人问过(我找不到),请道歉

谢谢, 伊万

这不起作用:

var Home = React.createClass({ ... });

var Component = "Home";
React.render(<Component />, ...);

使用JSX时,可以呈现HTML标记(字符串)或React组件(类)

当您执行var Tag=Home时,它会工作,因为JSX编译器会将其转换为:

var Template = React.createElement(Tag, {});
变量标记在同一范围内并且是React类

    var Tag = Home = React.createClass({
                       render () {
                         return (
                         <div>Home layout</div>
                         )
                       }
                     });
你在干什么

var Template = React.createElement("aClassName", null);
但是“aClassName”不是有效的HTML标记


无需像Michelle的回答那样手动将类映射到字典或“注册表”。通配符导入语句已经是字典

   import * as widgets from 'widgets';
   var Type = widgets[this.props.template];
   ...
   <Type />

我完全可以这样做,以获得react组件的动态调度。事实上,我认为我参与了很多项目。

我也遇到了同样的问题,并且自己找到了解决方案。我不知道这是否是“最佳实践”,但它确实有效,我目前正在我的解决方案中使用它

您可以简单地使用“evil”eval函数动态创建react组件的实例。比如:

function createComponent(componentName, props, children){
  var component = React.createElement(eval(componentName), props, children);
  return component;
}
然后,只要在你想要的地方打电话:

var homeComponent = createComponent('Home', [props], [...children]);
如果它符合你的需要,也许你可以考虑这样的事情。


希望能有所帮助。

我想知道如何从从数据库加载的JSON规范中动态创建React类,所以我做了一些实验并找到了答案。我的基本想法是,我想通过GUI定义React应用程序,而不是在文本编辑器中键入代码

这与React 16.3.2兼容。注意
React.createClass
已移动到其自己的模块中

以下是基本部分的浓缩版本:

从“React”导入React
从“react dom/server”导入ReactDOMServer
从“创建反应类”导入createReactClass
常数规格={
//getDefaultProps
//getInitialState
//propTypes:{…}
渲染(){
返回React.createElement('div',null,'Some text to render')
}
}
常量组件=createReactClass(规范)
常量工厂=React.createFactory(组件)
const实例=工厂({/*props*/})
const str=ReactDOMServer.renderToStaticMarkup(实例)
console.log(str)
您可以在此处看到一个更完整的示例:


以下是它从字符串内容开始工作的方式,而不会像其他人建议的那样,将组件作为静态链接代码嵌入到包中

import React from 'react';
import { Button } from 'semantic-ui-react';
import createReactClass from 'create-react-class';

export default class Demo extends React.Component {
    render() {
        const s = "return { render() { return rce('div', null, rce(components['Button'], {content: this.props.propA}), rce(components['Button'], {content: 'hardcoded content'})); } }"
        const createComponentSpec = new Function("rce", "components", s);
        const componentSpec = createComponentSpec(React.createElement, { "Button": Button });
        const component = React.createElement(createReactClass(componentSpec), { propA: "content from property" }, null);

        return (
            <div>
                {component}
            </div>
        )
    }
}
BabelJS将其翻译为:

function render() {
  return (
    <div>
      <Button content={this.props.propA}/>
      <Button content='hardcoded content'/>
    </div>
  );
}
function render() {
  return React.createElement("div", null, React.createElement(Button, {
    content: this.props.propA
  }), React.createElement(Button, {
    content: "hardcoded content"
  }));
}
render() { return rce('div', null, rce(components['Button'], {content: this.props.propA}), rce(components['Button'], {content: 'hardcoded content'})); }
您可以按照上述步骤进行更换:

function render() {
  return (
    <div>
      <Button content={this.props.propA}/>
      <Button content='hardcoded content'/>
    </div>
  );
}
function render() {
  return React.createElement("div", null, React.createElement(Button, {
    content: this.props.propA
  }), React.createElement(Button, {
    content: "hardcoded content"
  }));
}
render() { return rce('div', null, rce(components['Button'], {content: this.props.propA}), rce(components['Button'], {content: 'hardcoded content'})); }
调用
createComponentSpec
函数将为React类创建规范

    var Tag = Home = React.createClass({
                       render () {
                         return (
                         <div>Home layout</div>
                         )
                       }
                     });
然后使用
createReactClass
将其转换为实际的React类

然后用
React.createElement
激活


您所需要做的就是从主组件
render
func返回它。

谢谢,我希望代码中不要有贴图/链接。我希望能够添加模板而不改变主代码库。这不可能吗?@ewan您可以构建某种全局注册表,并在使用
React.createClass
创建每个组件时注册它(例如,通过将其包装在函数调用或其他方式),但您肯定需要获得对实际组件的引用。Awesome@MichelleTilley!我的linter甚至简化为
var组件={Home,Other,}运行良好。我不会认为<代码> EVA/COD>是邪恶的,除非用户可以输入他们想要的任何东西。
function render() {
  return (
    <div>
      <Button content={this.props.propA}/>
      <Button content='hardcoded content'/>
    </div>
  );
}
function render() {
  return React.createElement("div", null, React.createElement(Button, {
    content: this.props.propA
  }), React.createElement(Button, {
    content: "hardcoded content"
  }));
}
render() { return rce('div', null, rce(components['Button'], {content: this.props.propA}), rce(components['Button'], {content: 'hardcoded content'})); }