Skip to content

Instantly share code, notes, and snippets.

@alexeyraspopov
Created May 10, 2019 17:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alexeyraspopov/bb27696cc08c6aaf3105ce610bd8ca76 to your computer and use it in GitHub Desktop.
Save alexeyraspopov/bb27696cc08c6aaf3105ce610bd8ca76 to your computer and use it in GitHub Desktop.

Assuming we have a state identity and state reducer

let resourceIdentity = Map();

function resourceReducer(state, action) {
  switch (action) {
    // ...
    default:
      return state;
  }
}

Which can be integrated to UI tree with context and hooks

export function ResourceProvider({ children }) {
  let resourceState = useReducer(resourceReducer, resourceIdentity);
  return <ResourceContext.Provider value={resourceState} children={children} />;
}

export function useResource() {
  return useContext(ResourceContext);
}

An edge case of such pattern is having a pile of composed providers in the root component, which bothers your eyes. If that's really the case and you're 100% sure all that state is persistent 100% of time, maybe it's easier to keep it outside of the tree anyway?

let ResourceStore = createStore(resourceReducer, resourceIdentity);

export function useResource() {
  let [state, setState] = useState(() => ResourceStore.getState());

  useEffect(() => {
    return ResourceStore.subscribe(() => {
      setState(ResourceStore.getState());
    });
  }, []);

  return [state, ResourceStore.dispatch];
}

The same API for consumers, the same reducer used, no providers needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment