React state behavior

前端 未结 1 1820
天涯浪人
天涯浪人 2021-01-21 17:45

So, recently I\'ve started a new project. I\'m only using functional components (not sure if that\'s a relevant statement for this issue).

I have initialized a state var

1条回答
  •  醉话见心
    2021-01-21 17:54

    React state updates are asynchronous and, separately, a state update results in your component function being called once the update has completed, which means you get a new selectedFields variable. The original selectedFields variable the first call to your component has never changes. That's why even your setTimeout version didn't pick up the change: It's looking at the old selectedFields variable, not the new one.

    Think of it this way: Your function is called when the component is in one state, and then called again when it's in a new state.

    Your function should use selectedFields to render, and issue state updates for it, but it should not have code in it that expects those state updates to have occurred other than that it gets the new state from the const [selectedFields, setSelectedFields] = useState([]); line.


    Separately, because state updates are asynchronous and can be "batched" where an update isn't done immediately and it's possible for another one to occur before your component is called again, this line is often incorrect:

    setSelectedFields([...selectedFields, msg]);
    

    Instead, you need the callback form:

    setSelectedFields(fields => [...fields, msg]);
    

    That way, if there are multiple updates to the fields that are batched together, later ones don't overwrite the changes from earlier ones.

    Unfortunately, the React documentation is unclear about when you need to use the callback version of the state setter function and when you can use state directly when updating state. Some parts show using the callback (setCount(oldCount => oldCount + 1)), others show updating directly (setCount(count + 1)). I've tried to get an answer on this, but unfortunately haven't been successful.

    0 讨论(0)
提交回复
热议问题