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.