I just want to say really good post! I like how you broke down the problem.
I wanted to point out that the useState does not mutate state, however, splice does mutate state. What you could do here is use slice which does the same thing as splice but without mutating the original array. And then you are correct that when calling setTags you want to create a new array. π
BTW I didn't know about that the ?. & the ?? features! Going to start using it tomorrow at work! Thanks! π
Thanks for your feedback! Your explanation about splice and slice is totally right and is another way to solve the state update issue.
I have been reproducing the argument variable mutation in a straightforward example on codesandbox.io to demonstrate that useState initialization passes its argument reference to output value. I have tried to find the cause in the source code, but I'm having a hard time finding out. I would appreciate any help or insight on that. :D
In the example, you are mutating the original array. The push method mutates the original array.
The reason why your example is working is that when you call updateComp, react triggers a re-render because there is a state change and thus your UI reflecting the changes to the array.
What you need to before updating an array is to make a copy of it so that you don't modify the original array. Then you can push/remove items in the clonedArray. and then you use the setValue method to update the value state. I reflected this in the code below using your example.
importReact,{useState}from"react";import"./styles.css";functionDisplayComp(props={}){// const [updateComp, doUpdateComp] = useState(false);constinitialState=props.data;// that instantiation causes props to mutate// const initialState = [...props.data]; // that instantiation keeps props cleanconst[value,setValue]=useState(initialState);consthandleClick=()=>{constvalueClone=[...value];valueClone.push((value[value.length-1]||1)*2);setValue(valueClone)// doUpdateComp(!updateComp); // that line causes component to re-render};return(<divclassName="App"><h1>ReactHooksstatemanagement</h1>
<buttononClick={handleClick}>Mutate</button>
<p>Initialstatevalue:{initialState.join("")}</p>
<p>usestatevalue:{value.join("")}</p>
</div>
);}exportdefaultfunctionApp(){return<DisplayCompdata={[21]}/>;
}
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
I just want to say really good post! I like how you broke down the problem.
I wanted to point out that the useState does not mutate state, however, splice does mutate state. What you could do here is use slice which does the same thing as
splice
but without mutating the original array. And then you are correct that when callingsetTags
you want to create a new array. πBTW I didn't know about that the
?.
& the??
features! Going to start using it tomorrow at work! Thanks! πconst tagsInitialState = [...(props?.tags ?? [])]
Thanks for your feedback! Your explanation about splice and slice is totally right and is another way to solve the state update issue.
I have been reproducing the argument variable mutation in a straightforward example on codesandbox.io to demonstrate that useState initialization passes its argument reference to output value. I have tried to find the cause in the source code, but I'm having a hard time finding out. I would appreciate any help or insight on that. :D
The optionnal chaining operator (?.) and nullish coalescing operator (??) are both currently stage 4 proposal. Make sure you are on the latest Babel version (at least 7.8.0)
It makes code really more predictable π
In the example, you are mutating the original array. The push method mutates the original array.
The reason why your example is working is that when you call
updateComp
, react triggers a re-render because there is a state change and thus your UI reflecting the changes to the array.What you need to before updating an array is to make a copy of it so that you don't modify the original array. Then you can push/remove items in the clonedArray. and then you use the
setValue
method to update thevalue
state. I reflected this in the code below using your example.