Implement a React hooks basic state management
const createContainer = (initialState) => { let globalState = initialState; const listeners = Object.fromEntries(Object.keys(initialState).map(key => [key, new Set()])); const setGlobalState = (key, nextValue) => { if (typeof nextValue === 'function') { globalState = { ... globalState, [key]: nextValue(globalState[key]) }; } else { globalState = { ... globalState, [key]: nextValue }; } listeners[key].forEach(listener => listener()); }; const useGlobalState = (key) => { const [state, setState] = useState(globalState[key]); useEffect(() => { const listener = () => { setState(globalState[key]); }; listeners[key].add(listener); listener(); // in case it's already changed return () => { listeners[key].delete(listener) }; // cleanup }, []); return [state, (nextValue) => setGlobalState(key, nextValue)]; }; return { setGlobalState, useGlobalState, }; };Copy the code
The forceUpdate above is

const useGlobalState = (key) => {
    const [state, setState] = useState(globalState[key]);
    useEffect(() => {
      const listener = () => {
        setState(globalState[key]);
      };
      listeners[key].add(listener);
      listener(); // in case it's already changed
      return () => { listeners[key].delete(listener) }; // cleanup
    }, []);
    return [state, (nextValue) => setGlobalState(key, nextValue)];
  };
Copy the code
We can rewrite forceUpdate to another form by taking advantage of the unwanted nature of the object

const useGlobalState = (key) => {
  const [, forceUpdate] = useState({});
  useEffect(() => {
    const listener = () => {
      forceUpdate({});
    };
    listeners[key].add(listener);
    listener(); // in case it's already changed
    return () => { listeners[key].delete(listener) }; // cleanup
  }, []);
  return [globalState[key], (nextValue) => setGlobalState(key, nextValue)];
};
Copy the code
We can rewrite the forceUpdate to another form using the increment value

const useGlobalState = (key) => {
  const [, forceUpdate] = useState(0);
  useEffect(() => {
    const listener = () => {
      forceUpdate(c => c + 1);
    };
    listeners[key].add(listener);
    listener(); // in case it's already changed
    return () => { listeners[key].delete(listener) }; // cleanup
  }, []);
  return [globalState[key], (nextValue) => setGlobalState(key, nextValue)];
};
Copy the code