不确定这是所谓的“pub/sub”模式还是“pub/sub”模式的一种形式。我正在尝试创建一个共享状态,以便不同的组件可以订阅它,并且只有在该状态有更新时才会更新。
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 />
</>
);
<script src="https://unpkg.com/@babel/standalone@7/babel.min.js"></script>
<script src="https://unpkg.com/react@17/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.production.min.js"></script>
<div id="root"></div>
<script type="text/babel">
const { useEffect, useReducer } = React;
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 />
</>
);
ReactDOM.render(<Example />, document.querySelector("#root"));
</script>
它似乎工作正常。我的问题是:
useState
或 useReducer
像一个通常会做的那样? 最佳答案
useState
( DEMO ) 或 useReducer
(DEMO)。 关于javascript - react : is this a good way to implement a shared state subscription?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66609157/