问题描述
案例 1:
const [present, setPresent] = useState([]);useEffect(() => {for (var j = 1; j
情况 2:
.Case 1:
const [present, setPresent] = useState([]);
useEffect(() => {
for (var j = 1; j <= totalPeriod; j++) {
setPresent([
...present,
{
period: j,
present: true,
},
]);
}
}, []);
Case 2:
const [present, setPresent] = useState([]);
let createPresent = [];
for (var j = 1; j <= totalPeriod; j++) {
createPresent = [
...createPresent,
{
period: j,
present: true,
},
]
}
useEffect(() => {
setPresent(createPresent);
}, []);
When I am trying to update the present state using loop in inside useEffect()
in Case 1, present state is not updating. But when I am separately using loop outside the useEffect()
and creating an array which I am then assigning to present state in case 2, the present state is getting updated.
What is the reason behind this? Why present state is not updating in Case 1?
In the below case, your present
state is not the result of each subsequent state update but rather the initial one which you had which is []
. React will batch these updates and not make them happen synchronously so effectively there will be just one state update with present
updated to latest entry in your for loop
.
const [present, setPresent] = useState([]);
useEffect(() => {
for (var j = 1; j <= totalPeriod; j++) {
setPresent([
...present,
{
period: j,
present: true,
},
]);
}
}, []);
In the below case, you are first assembling a createPresent
array with all the values you need and finally calling the state updator function i.e. setPresent
to set the state.
const [present, setPresent] = useState([]);
let createPresent = [];
for (var j = 1; j <= totalPeriod; j++) {
createPresent = [
...createPresent,
{
period: j,
present: true,
},
]
}
useEffect(() => {
setPresent(createPresent);
}, []);
In order to achieve the second behaviour with first, you can make use of the state updator callback which holds the previous state as the argument like so :-
const [present, setPresent] = useState([]);
useEffect(() => {
for (let j = 1; j <= totalPeriod; j++) {
setPresent(prevState=>[
...prevState,
{
period: j,
present: true,
},
]);
}
}, []);
Here also state update is batched but previous state is factored in before updating the next one.
When I say a batched state update, I mean there will only be a single render. You can verify that by doing console.log('render')
in your component's function body.
Note the use of let
instead of var
here since let
is scoped you will get the accurate value for the variable j
.
这篇关于为什么在 useEffect() 中使用循环时 useState 钩子不更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!