问题描述
我想了解react-redux,而且我完全不知道为什么不更新组件。我认为没有任何更新,因为react不会关注上下文更改的深度。但是即使有这些想法,我也不知道该怎么办,请帮我,我很累
const MainContext = React.createContext(null);
const createStore = (reducer,initialState) => {
let currentState = initialState;
let listeners = [];
const getState = () => currentState;
const dispatch = (action) => {
currentState = reducer(currentState,action);
listeners.forEach((listener) => listener());
};
const subscribe = (listener) => listeners.push(listener);
return { getState,dispatch,subscribe };
};
const useSelector = (selector) => {
const ctx = React.useContext(MainContext);
if (!ctx) {
return 0;
}
return selector(ctx.store.getState());
};
const usedispatch = () => {
const ctx = React.useContext(MainContext);
if (!ctx) {
return () => { };
}
return ctx.store.dispatch;
};
const Provider = ({ store,context,children }) => {
const Context = context || MainContext;
return <Context.Provider value={{ store }}>{children}</Context.Provider>
};
APP
const UPDATE_COUNTER = "UPDATE_COUNTER";
const CHANGE_STEP_SIZE = "CHANGE_STEP_SIZE";
const updateCounter = (value) => ({
type: UPDATE_COUNTER,payload: value,});
const changeStepSize = (value) => ({
type: CHANGE_STEP_SIZE,});
const defaultState = {
counter: 1,stepSize: 1,};
const reducer = (state = defaultState,action) => {
switch (action.type) {
case UPDATE_COUNTER:
return {
...state,counter: state.counter + action.payload,};
case CHANGE_STEP_SIZE:
return {
...state,stepSize: +action.payload,};
default:
return state;
}
};
const Counter = () => {
const counter = useSelector((state) => state.counter);
const stepSize = useSelector((state) => state.stepSize);
const dispatch = usedispatch();
return (
<div>
<button onClick={() => dispatch(updateCounter(-stepSize))}>-</button>
<span> {counter} </span>
<button onClick={() => dispatch(updateCounter(stepSize))}>+</button>
</div>
);
};
const Step = () => {
const stepSize = useSelector(
(state) => state.stepSize,(current,prev) => current === prev
);
const dispatch = usedispatch();
return (
<div>
<div>
Значение счётчика должно увеличиваться или уменьшаться на заданную
величину шага
</div>
<div>Текущая величина шага: {stepSize}</div>
<input
type="range"
min="1"
max="5"
value={stepSize}
onChange={({ target }) => dispatch(changeStepSize(target.value))}
/>
</div>
);
};
ReactDOM.render(
<Provider store={createStore(reducer,defaultState)}>
<Step />
<Counter />
</Provider>,document.getElementById("app")
);
解决方法
您的useSelector
挂钩被错误地实现,因为它从未订阅商店。因此,它永远不会在更新后再次检查状态-仅在组件由于其他原因碰巧重新呈现时。
有关React-Redux实际工作方式的详细信息,请参阅我的详尽帖子The History and Implementation of React-Redux和我的演讲ReactNext 2019: A Deep Dive into React-Redux。