2021年3月12日星期五

React: is this a good way to implement a shared state subscription?

Not sure if this is a so-called "pub/sub" pattern or a form of a "pub/sub" pattern. I am trying to create a piece of shared state so that different components can subscribe to it and only gets updated when there is an update with that state.

  const useForceUpdate = () => useReducer((state) => !state, false)[1];    const createSharedState = (reducer, initialState) => {    const subscribers = [];    let state = initialState;    const dispatch = (action) => {      state = reducer(state, action);      subscribers.forEach((callback) => callback());    };    const useSharedState = () => {      const forceUpdate = useForceUpdate();      useEffect(() => {        const callback = () => forceUpdate();        subscribers.push(callback);        const cleanup = () => {          const index = subscribers.indexOf(callback);          subscribers.splice(index, 1);        };        return cleanup;      }, []);      return [state, dispatch];    };    return useSharedState;  };    const initialState = 0;  const reducer = (state, action) => {    switch (action.type) {      case "increment":        return state + 1;      case "decrement":        return state - 1;      case "set":        return action.count;      default:        return state;    }  };    const useCount1 = createSharedState(reducer, initialState);  const useCount2 = createSharedState(reducer, initialState);    const Counter = ({ count, dispatch }) => (    <div>      {count}      <button onClick={() => dispatch({ type: "increment" })}>+1</button>      <button onClick={() => dispatch({ type: "decrement" })}>-1</button>      <button onClick={() => dispatch({ type: "set", count: 0 })}>reset</button>    </div>  );    const Counter1 = () => {    const [count, dispatch] = useCount1();    return <Counter count={count} dispatch={dispatch} />;  };    const Counter2 = () => {    const [count, dispatch] = useCount2();    return <Counter count={count} dispatch={dispatch} />;  };    const Example = () => (    <>      <Counter1 />      <Counter1 />      <Counter2 />      <Counter2 />    </>  );  

Here is a live demo: https://codesandbox.io/s/pubsub-q716s?file=/src/App.js

It seems to be working fine. My questions are:

  1. Is this a valid way to implement shared update subscription?
  2. Is there any drawbacks with using a simple variable to hold the state + forcing React to re-render if that piece of state changes, instead of using useState or useReducer as one normally would do?
  3. any feedback is welcomed.
https://stackoverflow.com/questions/66609157/react-is-this-a-good-way-to-implement-a-shared-state-subscription March 13, 2021 at 09:05AM

没有评论:

发表评论