useEffect 在与 useReducer 一起使用时不会触发重新渲染
useEffect not triggering re-render when it's being used with useReducer
即使状态已更改,我也无法触发重新渲染。 PageContainer
调用 loadPage
和 loadPage
更新状态没有任何问题。
但是当状态改变时,它不会触发重新渲染。
它只显示初始状态(pageName.loginPage
)。我的预期结果是 pageName.profilePage
,因为令牌已存储在浏览器中。我还检查了调试器状态是否明显更改为 pageName.profilePage
function PageContainer() {
const { state, loadPage } = useContainer({
reducer: loginStatusCheckReducer,
});
useEffect(() => {
loadPage();
}, [state]); // or [state.page]
return (
<>
{state.page}
</>
);
}
这里是 useContainer
function useContainer({ reducer }) {
const [state, dispatch] = useReducer(reducer, { page: pageName.loginPage });
const loadPage = () => {
dispatch({ type: actionType.loadPage, dispatch });
};
return { state, loadPage };
}
这是reducer函数
function loginStatusCheckReducer(state, action) {
if (action.type === actionType.loadPage) {
const token = localStorage.getItem("token");
if (token) {
state.api = api(token);
state.page = pageName.profilePage;
return state;
}
}
return state;
}
初始状态:
在 loadPage
之后
查看代码,我猜这不会触发重新渲染,因为您的 useEffect 正在传递一个空数组,因此它不会对任何状态变化做出反应。
尝试添加 variable/state ,一旦加载到 useEffect
就会发生变化
function PageContainer() {
const { state, loadPage } = useContainer({
reducer: loginStatusCheckReducer,
});
useEffect(() => {
loadPage();
}, [state]); // here the effect will listen to state changes
console.log('state.page', state.page);
return (
<>
<h1>{state.page}</h1>
</>
);}
以下代码应该可以解决这个问题。 @lon 已经指出,state 不应该被直接改变。
function loginStatusCheckReducer(state, action) {
if (action.type === actionType.loadPage) {
const token = localStorage.getItem("token");
if (token) {
//state.api = api(token);
//state.page = pageName.profilePage;
//return state;
return {
...state,
api: api(token),
page: pageName.profilePage,
};
}
}
}
即使状态已更改,我也无法触发重新渲染。 PageContainer
调用 loadPage
和 loadPage
更新状态没有任何问题。
但是当状态改变时,它不会触发重新渲染。
它只显示初始状态(pageName.loginPage
)。我的预期结果是 pageName.profilePage
,因为令牌已存储在浏览器中。我还检查了调试器状态是否明显更改为 pageName.profilePage
function PageContainer() {
const { state, loadPage } = useContainer({
reducer: loginStatusCheckReducer,
});
useEffect(() => {
loadPage();
}, [state]); // or [state.page]
return (
<>
{state.page}
</>
);
}
这里是 useContainer
function useContainer({ reducer }) {
const [state, dispatch] = useReducer(reducer, { page: pageName.loginPage });
const loadPage = () => {
dispatch({ type: actionType.loadPage, dispatch });
};
return { state, loadPage };
}
这是reducer函数
function loginStatusCheckReducer(state, action) {
if (action.type === actionType.loadPage) {
const token = localStorage.getItem("token");
if (token) {
state.api = api(token);
state.page = pageName.profilePage;
return state;
}
}
return state;
}
初始状态:
在 loadPage
之后
查看代码,我猜这不会触发重新渲染,因为您的 useEffect 正在传递一个空数组,因此它不会对任何状态变化做出反应。
尝试添加 variable/state ,一旦加载到 useEffect
就会发生变化function PageContainer() {
const { state, loadPage } = useContainer({
reducer: loginStatusCheckReducer,
});
useEffect(() => {
loadPage();
}, [state]); // here the effect will listen to state changes
console.log('state.page', state.page);
return (
<>
<h1>{state.page}</h1>
</>
);}
以下代码应该可以解决这个问题。 @lon 已经指出,state 不应该被直接改变。
function loginStatusCheckReducer(state, action) {
if (action.type === actionType.loadPage) {
const token = localStorage.getItem("token");
if (token) {
//state.api = api(token);
//state.page = pageName.profilePage;
//return state;
return {
...state,
api: api(token),
page: pageName.profilePage,
};
}
}
}