Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Idea: Fractal stores: expose substore with attached local component scoped reducer #57

Open
ambientlight opened this issue Feb 1, 2020 · 0 comments

Comments

@ambientlight
Copy link
Contributor

ambientlight commented Feb 1, 2020

This made way to angular redux bindings fractal-store.md, which popped out while reviewing the code I wrote previously where I found myself doing something like:

  1. decorate a local reducer with global dispatch
[@react.component]
  let make = (~dispatch, ~mode: mode, ~title) => {
    let reducer = React.useMemo1(() => withPropagate(dispatch) @@ authReducer, [|dispatch|]);
    //...
}
  1. as local reducer operates on local components hook's useReducer store, I would relay(or passthrough) certain actions to the global store with such decorator function:
let withPropagate = (dispatch, reducer) => (state, action) => {
  switch(action){
  | `VerificationCodeChanged(verificationCode, username) => {
    // impure (modify local state and relay the action to the global store)
    String.length(verificationCode) == 6
      ? dispatch(`ConfirmSignUpRequest(verificationCode, username))
      : ();
    reducer(state, action)
  }
  // .... 
  | _ => reducer(state, action)
  };
};

loosely speaking I am having a global reductive state which is shared across the entire application, while components have their own isolated states that rely on useReducer hook originated states, in few cases there is cross-section between them, where I break single source of truth but have a one-way dataflow where component store update is relayed to the global store.

I am thinking to look on the alternative where the component store is moved to a global as a substore while keeping a reducer local with a component that operate on the substore.

Existing useSelector allows exposing a substore to a component, however having a centralized reducer, I am curious about your thoughts on the idea where substore allows injecting a local reducer? I'm not really sure this is really good idea in particular as It makes me feel it increases the inherent dynamism brought by this feature as those local reducers can be tied to component lifecycle where components will keep doing replaceReducer sort of stuff (same issue as in hooks where useMemo alleviates this), but I found it handy on the angular-redux side.

Not to mention additional complexity introduced by this (though can be achieved outside of reductive via store or reducer composition). The way that angular-redux implements this:

  1. dispatching an action to a substore will dispatch it to the global redux store with appended keypath of substore, while rootReducer is composed with another reducer(rootFractalReducer)
  2. this rootFractalReducer that will run prior to the main reducer will extract the keypath from an action, finds registered substore reducer in its internal dictionary store by this keypath, and then combine the results on this reducer with a main store.

Reference: fractal-reducer-map

The closest relevant discussion I found in original redux is reduxjs/redux#159 (comment) though @gaearon is referring there to ephermal state which is not the same thing as locking down to a substate with hooked up reducer.

Anyway, I felt this is worth a discussion so I am really curious to get your feedback on this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant