DEV Community

Global state management in React with global variables and hooks. State management doesn't have to be so hard.

Yezy Ilomo on May 27, 2020

Introduction First of all I'd like to talk a little bit about state management in react. State management in react can be divided into t...
Collapse
 
supunkavinda profile image
Supun Kavinda

We use your state-pool in our production system and it works great. We don't have to worry about hard-to-maintain Context API. Thank you very much for the innovative work. Also, I wonder why React doesn't support this approach by default.

Also, I've created a minified version (200 bytes gziped) of state-pool for Preact (github.com/SupunKavinda/preact-glo...), with one hook, useGlobalState.

Btw, I saw that you are using immer as an dependency. Is it for the reducer?

Collapse
 
shang profile image
Shang

Hi @supunkavinda
I installed your package and tried to use it. But I keep getting this error.

TypeError: Cannot read properties of undefined (reading 'H')
at d (localhost:9000/
runFrame/bundle.js:45827:419)
at s (localhost:9000/__runFrame/bundle.j...)
at h (localhost:9000/__runFrame/bundle.j...)
at useGlobalState (localhost:9000/__runFrame/bundle.j...)
at CareerStoryApp (localhost:9000/__runFrame/bundle.j...)
at renderWithHooks (localhost:9000/__runFrame/bundle.j...)
at mountIndeterminateComponent (localhost:9000/__runFrame/bundle.j...)
at beginWork (localhost:9000/__runFrame/bundle.j...)
at HTMLUnknownElement.callCallback (localhost:9000/__runFrame/bundle.j...)
at Object.invokeGuardedCallbackDev (localhost:9000/__runFrame/bundle.j...)
at invokeGuardedCallback (localhost:9000/__runFrame/bundle.j...)
at beginWork$1 (localhost:9000/__runFrame/bundle.j...)
at performUnitOfWork (localhost:9000/__runFrame/bundle.j...)
at workLoopSync (localhost:9000/__runFrame/bundle.j...)
at performSyncWorkOnRoot (localhost:9000/__runFrame/bundle.j...)
at scheduleUpdateOnFiber (localhost:9000/__runFrame/bundle.j...)
at updateContainer (localhost:9000/__runFrame/bundle.j...)
at localhost:9000/__runFrame/bundle.j...
at unbatchedUpdates (localhost:9000/__runFrame/bundle.j...)
at legacyRenderSubtreeIntoContainer (localhost:9000/__runFrame/bundle.j...)
at Object.render (localhost:9000/__runFrame/bundle.j...)
at initializeBlock (localhost:9000/__runFrame/bundle.j...)
at ./frontend/index.js (localhost:9000/__runFrame/bundle.j...)
at webpack_require (localhost:9000/__runFrame/bundle.j...)
at runBlock (localhost:9000/__runFrame/bundle.j...)
at static.airtable.com/js/by_sha/a663...

Collapse
 
supunkavinda profile image
Supun Kavinda

Hey, I am no longer maintaining the package. Also, from my experience, global state using window variables can run into many pitfalls. Use nanostores if possible.

Thread Thread
 
shang profile image
Shang

Hi, thanks for your fast reply.
Okay, I will consider using nanostores.
But when you use state-pool package, did you run without any errors?
I get keeping this error.

"TypeError: Cannot read properties of undefined (reading 'setState')"

This error indicates store.setState("count", 0);

Can you please guide me?
Thank you!

Thread Thread
 
supunkavinda profile image
Supun Kavinda

Sorry, I haven't used it in a long while

Thread Thread
 
shang profile image
Shang

Okay anyway.
Thanks!

Collapse
 
yezyilomo profile image
Yezy Ilomo

Immer is used for object comparisons to make sure that even a small change in object property triggers re-render to all components subscribed to a related global state.

Collapse
 
mbjelac profile image
Marko Bjelac

haven't checked the lib implementation but checking whether the new value is different then the old with === doesn't work on objects (just checks the heap reference). would this be desirable?

Collapse
 
yezyilomo profile image
Yezy Ilomo

Lib implementation depends on immer to compare objects, so it works just fine.

Collapse
 
ivan_jrmc profile image
Ivan Jeremic

Don't use this in production please. It does not work perfectly with react and is not implemented correctly. React recommends useSyncExternalStore for library authors maybe you should take a look.

Collapse
 
samdasoxide profile image
Samuel Ramdas

Yezy nice post,
In your reRender(newState) function you give it a newState parameter not sure how this is used. How would go wrong if the function doesn't have that parameter?

Collapse
 
yezyilomo profile image
Yezy Ilomo

Thanks for the feedback, I haven't showed its purpose in this post so you can safely ignore it but the intention was to pass it in case you want to avoid re-rendering if the global value hasn't changed, which in that case you would compare the old value and the new value and decide weather to rerender or not, so in short its purpose is to avoid unnecessary rerenders which is something I haven't showed in this post. You can check how I've used it in my library I mentioned to accomplish that.