简体   繁体   中英

Why are consecutive setState calls in async functions not batched?

So I understand that the setState calls are batched inside react event handlers for performance gains but why I don't understand is why are they not batched for setState calls in async callbacks.

for example: Suppose I have below code in one of the hooks.

fetch(url).then(res => res.json())
then((data)=>{
  setLoader(false);
  setData(data);
})

these two setState calls will lead to two different renders even though they are consecutive or synchronous to each other in a way.

I want to understand why cant we batch atleast these kind of setState calls which are right next to each other.Is this due to technical limitation or is there a reason why it was chosen to not do so?

This issue discusses when setState is batched and when it isn't:

https://github.com/facebook/react/issues/14259

To summarize:

React currently will batch state updates if they're triggered from within a React-based event, like a button click or input change. It will not batch updates if they're triggered outside of a React event handler, like a setTimeout().

React wraps your event handlers in a call to unstable_batchedUpdates(), so that your handler runs inside a callback. Any state updates triggered inside that callback will be batched. Any state updates triggered outside that callback will not be batched. Timeouts, promises, and async functions will end up executing outside that callback, and therefore not be batched.

The thread also has some suggestions for how to get around this "problem" using useReducer instead of useState . Here's an example, though I haven't tried it to see if it would work:

const [ state, dispatch, batch ] = useReducer(reducer, initialState);

batch(() => {
  dispatch(..);
  dispatch(..);
  // etc..
})

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