dai-shi / use-context-selector

React useContextSelector hook in userland
https://www.npmjs.com/package/use-context-selector
MIT License
2.68k stars 61 forks source link

Update occurs asynchronously after selection function runs #113

Closed benwiley4000 closed 9 months ago

benwiley4000 commented 9 months ago

This seems like it's almost definitely a bug. I'm aware that the context can notify subscribers asynchronously of context changes, causing potential out-of-sync-ness. This is not that issue.

This issue is that when useContextSelector's callback function runs and returns a new value, at least sometimes, the returned value immediately afterward can still be the old value.

My workaround fix is to go from this:

const mySelectedContextValue = useContextSelector(context =>
  getMemoizedContext(context, context.changingProperty)
);

To this:

const mySelectedContextValueRef = useRef(defaultContextValue);
useContextSelector(context =>
  mySelectedContextValueRef.current = getMemoizedContext(context, context.changingProperty)
);
const mySelectedContextValue = mySelectedContextValueRef.current;

Note that I tested getMemoizedContext and its value is indeed changing when it needs to.

dai-shi commented 9 months ago

It's how React works, like useState too. This library is to emulate React behavior. If you need a global variable outside React (which isn't async), various global state libraries would work for you, and Zustand would be the one.