question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. ItĀ collects links to all the places you might be looking at while hunting down a tough bug.

And, if youā€™re still stuck at the end, weā€™re happy to hop on a call to see how we can help out.

Namespacing / slicing application state alike Redux' combineReducers

See original GitHub issue

Hey!

I just came across this library, and am quite enthusiastic already šŸ„³

Iā€™ve ditched Redux in the past, only to have returned to adding it back later because of a need for a common-sense global application state instance when using various somewhat-interdependent contexts didnā€™t work out better than Redux in the first place.

One think I really dislike about Redux, is the ergonomic pain of having to differentiate between synchronous and asynchronous (or otherwise indirect) operations. This always feels like a ā€œfakeā€ or accidental technically-contrained version of a private/public layered approach. Often, the set of ordinary actions end up kind of like a private store api, and the async actions (or otherwise indirect thunks) end up like the public api.

Zustand seems to nicely eliminate this distinction from it ergonomics, retaining the same general approach but without the ā€œbureaucratic fussā€ letā€™s say.

const useStore = create((set, get, api) => {
  // set up the state layout
  const initialState = { ... };
  // some internal helpers
  const privateFn = (...) => { ... get() ... set(...) ... };
  // the public api
  const publicFn = (...) => { ... get() ... privateFn(...) ... };
  return {
    ...initialState,
    publicFn,
    ...
  };
});

Iā€™m tempted to look into replacing Redux for Zustand in my (medium-scale, web & native) app, but would first need to concoct/add a few tools to be able to transition from what we have now. Up top on that list is the ability to divide the top-level state into somewhat independent ā€œslicesā€, e.g. combineReducers in Redux.

Hereā€™s a little attempt I made at something that would look similar, but maybe be a bit more flexible than a drop-in combineCreators (which was my first idea):

https://codesandbox.io/s/zustand-combinecreators-ojew5?file=/src/App.tsx

const useStore = create((get, set, api) => {
  const counterSlice = namespace("counter", createCounter)(get, set,  api);
  ...
  const crossSliceOperation = (...) => { ... };

  return {
    counter: counterSlice,
    crossSliceOperation,
    ...
  };
});

(Also, typing all of this is not super trivial, and probably requires some overloading of SetState etc.)

What are your thoughts?

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:1
  • Comments:10 (6 by maintainers)

github_iconTop GitHub Comments

42reactions
dai-shicommented, Feb 11, 2021

Several people seem to be interested in this.

19reactions
dhmk083commented, Dec 29, 2021

I created a helper package to deal with nested sub-stores: zustand-lens

You can define a sub-store like this:

const subStore = lens((set, get) => ...)

Here, set and get are identical to zustandā€™s original create((set, get) => ), but they are scoped to sub-store.

This way you can have multiple independent sub-stores which donā€™t care about parent state shape:

const useStore = create(withLenses(() => ({
  bears: lens(set => ({
    // ...bears state & actions
  })),

  fish: lens(set => ({
    // ...fish state & actions
  }))
})))

If your sub-stores need each otherā€™s state, just use global set and get functions.

Read more comments on GitHub >

github_iconTop Results From Across the Web

combineReducers(reducers) - Redux
This function helps you organize your reducers to manage their own slices of state, similar to how you would have different Flux Stores...
Read more >
Namespacing Actions for Redux - Kickstarter Engineering
With Redux, you can use combineReducers to create nested reducers that only operate on a slice of state, but all reducers still respond...
Read more >
Split your Redux Store into Multiple Reducers - Egghead.io
... rely on the combineReducers method from redux. Once we split up out reducers, I then show how to access the state using...
Read more >
How to dynamically load reducers for code splitting in a Redux ...
Redux examples show that I should use combineReducers() to generate one reducer. Also as I understand Redux application should have one store and...
Read more >
Namespacing Ā· Redux Subspace - GitHub Pages
Let's change our application to use the same reducer for both subApp1 and subApp2 : ... combineReducers } from 'redux' const counter =...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found