1

I have to load different react component for different input types. I dont want to use switch case as this will become very huge. So i have created a map for each type and component to be loaded and using a variable to populate the final render component name. But this is not working.

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>)
    }
}

right now example show only one component, because i was testing if this approach works or not. what I am missing here.

2 Answers 2

3

FIELD_COMPONENTS_CLASSES_MAP[this.state.field._data.type] returns string, not a component object.

Your FIELD_COMPONENTS_CLASSES_MAP has should have references to the component objects, not their string names.

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

const FIELD_COMPONENTS_CLASSES_MAP = {
    text: FieldsComponent,
    phone: FieldsComponent,
    email: FieldsComponent,
    //...
};
Sign up to request clarification or add additional context in comments.

Comments

0

You need to assign the component itself as the value to the key. See the example.

Hope it helps!

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'))
<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>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.