Preview:
import { useCallback, useEffect } from 'react';
import { useDispatch, useSelector, useStore } from 'react-redux';
import { combineReducers } from 'redux';

// add to store object
// const reducerMap = {
// };
// store.reducerMap = reducerMap;
//


const useSharedValue = (key, defaultValue) => {
  const reducer = useCallback(
    (state = defaultValue, action) => {
      switch (action.type) {
        case `SHARED_VALUE_ACTION_KEY/${key}`:
          return action.payload.value;

        default:
          return state;
      }
    },
    [key, defaultValue],
  );
  const action = useCallback(
    value => ({
      type: `SHARED_VALUE_ACTION_KEY/${key}`,
      payload: { value },
    }),
    [key],
  );
  const selector = useCallback(() => state => state[key] || defaultValue, [
    defaultValue,
    key,
  ]);

  const store = useStore();
  useEffect(() => {
    if (store?.reducerMap) {
      store.replaceReducer(
        combineReducers({
          ...store.reducerMap,
          [key]: reducer,
        }),
      );
      store.reducerMap[key] = reducer;
    }
  }, [store, reducer, key]);

  const data = useSelector(selector());
  const dispatch = useDispatch();
  const set = useCallback(value => dispatch(action(value)), [dispatch, action]);

  return {
    data,
    set,
  };
};
downloadDownload PNG downloadDownload JPEG downloadDownload SVG

Tip: You can change the style, width & colours of the snippet with the inspect tool before clicking Download!

Click to optimize width for Twitter