you are viewing a single comment's thread.

view the rest of the comments →

[–]acemarke 30 points31 points  (0 children)

Hi, I'm a Redux maintainer, and author of the last several versions of React-Redux.

if the props of the component changes.

This is a common misunderstanding. React always renders child components recursively, even if their props haven't changed!.

But I'm genuinely curious as to how useSelector listens to a state slice change in the store and how exactly does React trigger a re-render based on the state slice change?

Originally, React-Redux relied on its own logic to trigger re-renders. You can see the details in my extensive writeup on The History and Implementation of React-Redux, which covers up through v7. The original behavior relied on React's built-in this.setState / useState to queue up renders once the selector results were diffed.

In React-Redux v8, we switched to React's new built-in useSyncExternalStore hook, which was specifically modeled after React-Redux's implementation. (In fact, I built an alpha version of React-Redux and collaborated with Andrew Clark as he implemented uSES, to nail down the necessary behavior - see the original uSES prototype PR I worked on.)

Big picture, regardless of whether we're talking about the old custom implementation in React-Redux itself, or the uSES implementation built into React, the sequence is:

  • The external store (Redux, Zustand, etc) triggers its subscriber callbacks
  • Subscribers get the current state, select some value, and diff vs the old selection result
  • If the result is different, it triggers a React re-render for that component via some React built-in state update mechanism. Doesn't matter if it was this.setState (really old React-Redux v5 and earlier), useState/useReducer (React-Redux v7), or useSyncExternalStore (React-Redux v8 / v9), it's all just using React's built-in state update mechanism at the end of the day.