Reputation: 740
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.
Upvotes: 1
Views: 1260
Reputation: 19113
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>
Upvotes: 0
Reputation: 12882
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,
//...
};
Upvotes: 3