Reading questions about useState
hook I was thinking about setState
. I'm always using intentionally the setState
with the callback option to access the previous state and have all the elements for example in an array.
So I have made a quick example for representation in a functional component:
const [elems, setElems] = useState([]);
const addElemsMutate = (count) => {
const newArray = [...elems];
for (let i = 0; i < count; i++) {
newArray.push(i);
}
setElems(newArray);
};
const addElemsUsePreviousState = (count) => {
for (let i = 0; i < count; i++) {
setElems(previousElems => [...previousElems, i]);
}
}
return <>
<button onClick={() => addElemsMutate(10)}>addElemsMutate</button>
<button onClick={() => addElemsUsePreviousState(10)}>addElemsUsePreviousState</button>
{elems.map((e, index) => <span key={index}>{e}</span>)}
</>
Question
I understand the setState
is asynchronous , enqueues changes and it should not be directly mutated as the documentation states .
The result form both of the actions look the same on the UI. So my question is about what I have in addElemsMutate
function:
Thanks!
There's a lot going on here that may not be intentional:
addElemsMutate()
doesn't actually mutate the state.addElemsUsePreviousState()
enqueues count
state changes instead of the single one dispatched by addElemsMutate()
. You can combine the callback form of useState()
with useCallback()
as a small performance optimization.
const addElemsCallback = useCallback(count => {
setElems(elems => {
const newElems = [...elems];
for (let i = 0; i < count; i++) {
newElems.push(i);
}
return newElems;
});
}, [setElems]);
Since setElems
never changes, neither does addElemsCallback
, and it's the only thing you need to pass as a dependency.
React best practices for changing states is to copy the current state into a new variable, make the changes there, and then change the state (as you have done so in your example).
This is because, when you change the state directly, instead of deep copying what the previous state was, you run into issues with references, which can leave some hard to find bugs.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.