简体   繁体   中英

React hooks how to only execute side effect function only once if I need to update 2 dependency variables

Lets say I have the following component using react hooks

const Component = (props) => {
   [state1, setState1] = useState();
   [state2, setState2] = useState();
   useEffect(()=>{
       // use state1 and state2 as param to fetch data
       ...
   }, [state1, state2])

   onSomethingChange = () => {
       setState1(...);
       setState2(...);
   }

   return (..);
}

When onSomethingChange triggers, I thought it would call the side effect function twice since I update 2 different state vars in the same dependency array. And I was going to refactor those 2 vars into 1 object but I thought I would test them as 2 separate vars first.

What I observed is the side effect function only gets executed once even when I update 2 different state vars in the same dependency array, this is what I wanted but I don't know why. Could someone please explain how it works under the bonnet?

That's because React sometimes may batch multiple state changes into one update for performance. React will batch state updates if they're triggered from within a React-based event, that's the reason why your side effect block is called only once. For more information, you may refer this thread: https://github.com/facebook/react/issues/14259

React batches state updates under the hood.

That simply means that calling

setState1(...);
setState2(...);

in the same synchronous (!) execution cycle (eg in the same function) will NOT trigger two component re-render cycles.

Instead, the component will only re-render once and both state updates will be applied simultaneously.

Not directly related, but also sometimes misunderstood, is when the new state value is available.

Consider this code:

console.log(name); // prints name state, e.g. 'Doe'
setName('John');

console.log(name); // ??? what gets printed? 'John'?

You could think that accessing the name state after setName('John'); should yield the new value (eg 'John') but this is NOT the case.

The new state value is only available in the next component render cycle (which gets scheduled by calling setName()).

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