I'm learning react and while working on a bigger project I created this mockup to show the issue I'm having.
The parent component maintains a value in state which it passes to children via props. I want this value to propagate to children and update there when it is changed in the parent state. This works in the first version of this code:
import React from "react"
import Child from './Child'
export default class Parent extends React.Component {
constructor() {
super();
this.state = {
single_val: false,
}
}
render() {
return(
<div className="Parent" style={{border: "solid orange 1px", padding: "15px"}}>
<p>Parent val: {this.state.single_val.toString()}</p>
<Child parent_val={this.state.single_val}/>
<Child parent_val={this.state.single_val}/>
<Child parent_val={this.state.single_val}/>
<div className="switch"
style={{height: "50px", width: "50px", backgroundColor: "lightPink"}}
onClick={(e)=>{this.setState({single_val: true})}}
>
</div>
</div>
)
}
}
However, in the final version of the project, I need to create the children dynamically. I do it like this:
import React from "react"
import Child from './Child'
export default class Parent extends React.Component {
constructor() {
super();
this.state = {
single_val: false,
children_divs: [],
}
this.setUp = this.setUp.bind(this);
}
componentDidMount() {
this.setUp();
}
setUp() {
var baseArray = [...Array(3)];
var children = baseArray.map((elem)=>{
return (<Child parent_val={this.state.single_val} />)
});
this.setState({children_divs: children});
}
render() {
return(
<div className="Parent" style={{border: "solid orange 1px", padding: "15px"}}>
<p>Parent val: {this.state.single_val.toString()}</p>
{this.state.children_divs}
<div className="switch"
style={{height: "50px", width: "50px", backgroundColor: "lightPink"}}
onClick={(e)=>{this.setState({single_val: true})}}
>
</div>
</div>
)
}
}
...and the value no longer propagates to children when I press the button and change the parent's state: results screenshots.
How to keep the dynamic creation of child divs and still have the parent value propagate? I sense the issue might me because the value and children divs array are both maintained in the parent state but I'm not sure how to fix it. Hours of searching and looking at examples suggest I should recreate children divs from scratch - run the setUp again - but it seems like an overkill for one state value that I thought should propagate anyway.
Child component code for reference:
import React from "react"
export default function Child(props) {
return (
<div className="Child">
<p>Child val: {props.parent_val.toString()}</p>
</div>
)
}
P.S. I even experimented with adding componentDidUpdate() to children to try and receive props again, but it never triggered.
Ok, so the problem here is your
children_divsare created once and value ofsingle_valis added/sent to them at that time (when you have created them insetUpfunction. Solution is simple, have your children created inrenderfunction, asrenderis called each time yourstatechanges. This also removes yourchildren_divsfrom state as its only used to render and serve no other purpose.