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
 
supunio profile image
Supun Wimalasena •

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
 
supunio profile image
Supun Wimalasena •

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
 
supunio profile image
Supun Wimalasena •

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

Thread Thread
 
shang profile image
Shang •

Okay anyway.
Thanks!

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
 
ivanjrmc 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.