从字符串名称动态加载反应组件

时间:2016-11-02 08:44:42

标签: reactjs react-jsx

我必须为不同的输入类型加载不同的反应组件。我不想使用开关盒,因为这将变得非常巨大。所以我为每个要加载的类型和组件创建了一个映射,并使用一个变量来填充最终的渲染组件名称。但这不起作用。

const FIELD_COMPONENTS_CLASSES_MAP = {
    text: 'FieldsComponent',
    phone: 'FieldsComponent',
    email: 'FieldsComponent',
    decimal: 'FieldsComponent',
    date: 'FieldsComponent',
    datetime: 'FieldsComponent',
    location: 'FieldsComponent',
    meeting: 'FieldsComponent',
    number: 'FieldsComponent',
    multi_select_check_box: 'FieldsComponent',
    code_name_spinner: 'FieldsComponent',

};
export default class FieldsFactoryComponent extends React.Component {
    constructor(props, context) {
        super(props, context);
        this.state = {field: this.props.field, options: this.props.options};
    }

    componentWillReceiveProps(nextProps) {
        this.setState({field: nextProps.field, options: nextProps.options});
    }

    render() {
        let Component = 'FieldsComponent';
        if(this.state.field) {
            Component = FIELD_COMPONENTS_CLASSES_MAP[this.state.field._data.type]
        }

        return (this.state.field ?
            <Component field={this.state.field} options={this.state.options}
                             onSave={this.props.onSave}> </Component> : <div className="hidden"></div>)
    }
}

现在示例只显示一个组件,因为我正在测试这种方法是否有效。我在这里失踪了。

2 个答案:

答案 0 :(得分:3)

FIELD_COMPONENTS_CLASSES_MAP[this.state.field._data.type]返回字符串,而不是组件对象。

您的FIELD_COMPONENTS_CLASSES_MAP应该引用组件对象,而不是它们的字符串名称。

const FieldsComponent = props => {
  return (
    <p>Foo</p>
  )
} 

const FIELD_COMPONENTS_CLASSES_MAP = {
    text: FieldsComponent,
    phone: FieldsComponent,
    email: FieldsComponent,
    //...
};

答案 1 :(得分:0)

您需要将component本身作为键的值。 参见示例。

希望它有所帮助!

&#13;
&#13;
class A extends React.Component{
  render(){
    return <h1>Hello! I'm A</h1>
  }
}

class B extends React.Component{
  render(){
    return <h1>Hello! I'm B</h1>
  }
}

const map = {
  A, //equal to A: A
  B, //equal to B: B
}

class App extends React.Component{
  constructor(){
    super()
    this.onChange = this.onChange.bind(this)
    this.state = {
      component: 'A'
    }
  }
  onChange(e){
    this.setState({
      component: e.target.value
    })
  }
  
  render(){
    const Component = map[this.state.component || 'A']
    return <div>
      <select onChange={this.onChange} selected={this.state.component}>
        <option value="A">A</option>
        <option value="B">B</option>
      </select>
     <Component/>
    </div>
  }
}

ReactDOM.render(<App/>, document.getElementById('app'))
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>
&#13;
&#13;
&#13;