我试图搜索这个问题,但大部分主题都是关于 mutate,但在我的例子中它是一种原始数据类型,这里是示例代码:
// ParentPage.jsx
import { useSelector } from 'react-redux';
const selectShowFooterFlag = (state) => {
return state.shouldShowFooter;
}
const ParentPage = () => {
const shouldShowFooter = useSelector(selectShowFooterFlag);
const ChildComponent = useSelector(selectChildComponent);
return (
<p>{String(shoudShowFooter)}</p>
<ChildComponent shoudShowFooter={shoudShowFooter}>
)
}
export default ParentPage;
// ChildPage
const ChildPage = ({ shoudShowFooter }) => {
useEffect(() => {
dispatch(shouldShowFooterState(false));
return () => {
dispatch(shouldShowFooterState(true));
}
});
return (
<p>String(shoudShowFooter)</p>
)
}
// reducer
const initalState = {
isPageFooterRequired: true,
};
export const pagesReducer: (draft, action) = produce((draft = initialState, action: DispatchAction) => {
switch() {
case SHOW_FOOTER:
draft.shoudShowFooter = action.payload;
break;
default:
return draft;
}
});
在这个例子中,当子组件挂载时,它会按预期将 shoudShowFooter
设置为 false
。当 ChildComponent
在 redux store 中更新时,当前 ChildComponent 将卸载并将 shoudShowFooter
设置为 true
。我已经检查过了,它和预期的一样正确(selectShowFooterFlag
已被调用)。
但问题是 shoudShowFooter
在 redux 中发生了变化,但 ParentPage
没有使用新状态重新渲染,因此新的 ChildComponent 无法接收 reducer 存储中的最新数据(我已经检查过Redux devtools 提供的最新状态数据)。
更有趣的一点是,当我切换到使用连接时,一切正常。
import { connect } from 'react-redux';
const selectShowFooterFlag = (state) => {
return state.shouldShowFooter;
}
const ParentPage = () => {
const ChildComponent = useSelector(selectChildComponent);
return (
<p>{String(shoudShowFooter)}</p>
<ChildComponent shoudShowFooter={shoudShowFooter}>
)
}
const mapStateToProps = (state) => {
return {
shouldShowFooter: selectShowFooterFlag(state);
}
}
export default connect(mapStateToProps)(ParentPage);
我认为 useSelector 会给我们提供与连接相同的行为,当状态数据改变时会重新渲染组件。但似乎不是这种情况。
我怎样才能让 useSelector
触发使用最新数据重新渲染,就像 connect
所做的那样?或者我如何调试这个案例以了解为什么 React 不重新渲染应用程序?