我有一个组件订阅了商店的一部分并在之后触发一个效果
const Component = (name) => {
const query = useSelector((state) => getQuerySelector(state, name), shallowEqual);
useEffect(() => {
doStuff();
}, [query]);
}
选择器看起来像
const getQuerySelector = (state, name) => state.innerReducer[name].query;
即使当reducer用相同的值更新query
,比如{value: true}
(它是其他值的计算结果),选择器似乎每次都会更新。这是我的减速器的一部分:
case 'ACTION_X':
const query = {aProp: aValue, someOtherProp: someValue}
return {
...otherData,
query
}
我也尝试使用 memoize
createSelector
选择器,但没有成功。
答案 0 :(得分:0)
我无法使用您提供的所有代码重现您描述的行为。也许您可以使用我的代码片段来重现您所描述的行为:
const {
Provider,
useDispatch,
useSelector,
shallowEqual,
} = ReactRedux;
const { createStore, applyMiddleware, compose } = Redux;
const name = 'name';
const initialState = {
innerReducer: {
name: {
query: { aProp: 8, someOtherProp: 8 },
},
},
};
//action types
const ACTION_X = 'ACTION_X';
//action creators
const actionX = () => ({
type: ACTION_X,
});
const reducer = (state, { type }) => {
console.log('reducing action:', type);
if (type === ACTION_X) {
const query = { aProp: 8, someOtherProp: 8 };
return {
...state,
innerReducer: {
...state.innerReducer,
[name]: {
...state.innerReducer[name],
query,
},
},
};
}
return state;
};
//selectors
const getQuerySelector = (state, name) =>
state.innerReducer[name].query;
//creating store with redux dev tools
const composeEnhancers =
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(
reducer,
initialState,
composeEnhancers(
applyMiddleware(() => (next) => (action) =>
next(action)
)
)
);
const App = () => {
const query = useSelector(
(state) => getQuerySelector(state, name),
//this shallowEqual will make sure that
//{ aProp: 8, someOtherProp: 8 } quals { aProp: 8, someOtherProp: 8 }
shallowEqual
);
const dispatch = useDispatch();
console.log('rendering app');
React.useEffect(
() => console.log('Query in effect:', query),
[query]
);
return (
<div>
<button onClick={() => dispatch(actionX())}>
dispatch action x
</button>
<pre>{JSON.stringify(query, undefined, 2)}</pre>
</div>
);
};
console.log(
'using shallowEqual:',
shallowEqual(
{ aProp: 8, someOtherProp: 8 },
{ aProp: 8, someOtherProp: 8 }
)
);
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.0.5/redux.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-redux/7.2.0/react-redux.min.js"></script>
<div id="root"></div>
也许你可以看看 redux devtools 并确保查询状态没有改变。也许组件重新渲染是因为父组件被重新渲染而你的组件不纯,也许组件被重新渲染是因为父组件传入了不同的道具。组件重新呈现的原因可能有很多,但您问题中的代码没有显示任何内容。