'Set component's props dynamically
I need to set component's props after it is stored in a variable, here is pseudo code:
render(){
let items = [{title:'hello'}, {title:'world'}];
let component = false;
switch (id) {
case 1:
component = <A />
break;
case 2:
component = <B />
break;
}
return(
items.map((item, index)=>{
return(
<span>
{/* SOMETHING LIKE THIS WOULD BE COOL - IS THAT EVEN POSSIBLE*/}
{component.props.set('title', item.title)}
</span>11
)
})
)
}
Inside return I run a loop where I need to set props for the component that is stored inside a variable.... How to set props for this component which I stored earlier in a variable?
Solution 1:[1]
It can be done by assign not jsx but component reference, then use jsx in looping with using of component from variable. Check my code changes.
render(){
let items = [{title:'hello'}, {title:'world'}];
let C = null; //null is more accurate for object variable
switch (id) {
case 1:
C = A; //it is component reference, C must be from upper letter
break;
case 2:
C = B; //it is component reference
break;
default:
C = A; //good to have default for wrong ids
}
return(
items.map((item, index)=>{
return(
<span>
<C {...item} /> //render component with props
</span>11
)
})
)
}
Most important things:
1.C=A; we set on variable C reference to target component
2.<C {...item} /> all properties from item object will be set in child component.
3.It can be used in standard way like: <C title={item.title} />
Some working example: https://jsfiddle.net/maciejsikora/jtt91wL3/3/
Solution 2:[2]
More Use-cases Example -> for other people that came here:
A way of dynamically rendering all items from pre-declared array with all components and their props:
const items = [{component: Home,props:{ icon: 'fa-home', title: 'Home Page'}},{...}]
<div>
{
items.map((item) => {
let Child = item.component;
return (<Child {...item.props}/>);
});
}
</div>
Solution 3:[3]
You can move the switch inside the map(). Hope this helps!
class A extends React.Component{
render(){
return <h1>Inside Component A:{this.props.title}</h1>
}
}
class B extends React.Component{
render(){
return <h1>Inside Component B: {this.props.title}</h1>
}
}
class Parent extends React.Component{
render(){
let items = [{title:'hello'}, {title:'world'}];
const finalItems = items.map((item, index) => {
switch (parseInt(this.props.id)) {
case 1:
return <A title={item.title}/>
case 2:
return <B title={item.title}/>
}
})
return(
<span> {finalItems} </span>
)
}
}
ReactDOM.render(<div>
<Parent id="1"/>
<Parent id="2"/>
<Parent id="3"/>
</div>,
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>
You don't need to add a default case as React will ignore undefined, which will be returned to the map when the switch case fails.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | |
| Solution 3 |
