简体   繁体   中英

When using useState hook - Is there an importance to changing the setState functions call order?

I have a React functional component with two state variables ( itemsData & itemsCollections ). The variables are updated in the useEffect method. But after useEffect occur one of the state variables is null .

Upon switching the setStateFunctions ( setItemsData & setItemsCollect ) call order both arguments are inialized as expected.

How's that?

const MyComponent = ({itemsIds}) => {
   const [itemsData, setItemsData] = useState([]);
   const [itemsCollections, setItemsCollect] = useState({});

 useEffect(() => {
        fetchItemsData({ itemsIds }).then(({ items, itemCollect }) => {
             setItemsData(items);
             setItemsCollect(itemCollect);
        })
    }, [itemsIds]);
...
console.log('itemsData', itemsData) // the expected array
console.log('itemCollect', itemCollect) // empty objecy

State after useEffect: itemCollect = {}, itemsData = [{value:...},...]

Switching the order of the calls:

const MyComponent = ({itemsIds}) => {
   ...
 useEffect(() => {
        fetchItemsData({ itemsIds }).then(({ items, itemCollect }) => {
             setItemsCollect(itemCollect); // <--> switched rows
             setItemsData(items); // <--> switched rows

        })
    }, [itemsIds]);
...
console.log('itemsData', itemsData) // the expected array
console.log('itemCollect', itemCollect) // the expected object

State after useEffect: itemCollect = { someValue: ...} , itemsData = [{value:...},...]

There is a performance optimization called batching, which can change between React versions . When this optimization is applied, multiple setState calls will be batched together before the next render (and the order does not matter).

When not applied (eg inside a Promise as in your case, see Does React batch state update functions when using hooks? ), then each state update will trigger a new render (and the order matters).

=> console.log('itemCollect', itemCollect) may log different data in each render.

If you need to force a single state update, then calling a single dispatch from useReducer might be the best option.

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM