I am porting over a Backbone.View into React. I might be missing something, but I cannot figure out the idiomatic way to make the state of a component dependent on the states of their sibling. For example, say that I have a component like this:
<Timeline>
<Page selected="true" onClick={this.handleClick} />
<Page selected="false" onClick={this.handleClick}/>
</Timeline>
And let's say all handleClick does it to setState({selected: true})
. My question is how do I make sure that the state of the siblings of this component are set to false before it is set to true.
My ideal solution would be to listen for changes in prop state and forceRender the sub-components from the Timeline component, but I don't know if this is an accepted approach.
I am also looking for alternative ways to implement this component, since I understand the recommended way to decompose the components is to keep them as stateless as possible to ensure they can be reused elsewhere.
To listen for state changes in React, we use the useEffect hook. export function MyComponent(props) { const [myState, setMystate] = useState("initialState"); useEffect(() => { console. log(myState); }, [myState]); //... } to create the MyComponent component.
To update state when props change in React: Pass the props as dependencies to the useEffect hook. Every time the props change, the logic in useEffect is reran.
React components has a built-in state object. The state object is where you store property values that belongs to the component. When the state object changes, the component re-renders.
The state and props in React are always in an object format. This means that the value could be accessed from the state and props via key-value pair. To access the normal state object, you can use the key name from the object.
In cases where siblings seem to have interdependent state, you'll want to hoist up the relevant pieces of state up to the parent component.
In this case, you probably want to store selectedPage
on the parent's state object, causing the render method to look like
<Timeline>
<Page selected={this.state.selectedPage === 1} onClick={this.handleClick} />
<Page selected={this.state.selectedPage === 2} onClick={this.handleClick} />
</Timeline>
or similar. When you want to change the selected page, simply change the selectedPage
value stored on the parent, possibly from within a callback passed to the children.
By following this pattern, you can ensure that the two pages are always in sync with each other -- each time the parent rerenders the props will be updated simultaneously on the two children.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With