在渲染函数之外使用 useReducer() 的状态
Use of state from useReducer() outside of render function
我无法访问渲染函数之外的状态当前值。它总是return初始状态值
我有一个 signalR 连接,当我收到一条消息时,我想发送一个动作。 "problem" 是:我对两个状态对象使用相同的减速器。因此,我想检查一下我应该将 action 分派给哪一个。
减速器:
const processoReducer = (state, action) => {
switch (action.type) {
case "ProcessoIniciado":
return {...action.payload};
case "ItemIniciado":
return { ...state, iniciados: state.iniciados + 1 };
case "ItemConcluido":
case "ItemErro":
var arr = state.mbTiles.slice();
arr.pop();
return {
...state,
executados: state.executados + 1,
iniciados: state.iniciados - 1,
mbTiles: [action.payload, ...arr]
};
default:
return {...state};
}
};
组件:
const mbtiles = props => {
const [processoSetor, dispatchSetor] = useReducer(processoReducer, {});
const [processoUsuario, dispatchUsuario] = useReducer(processoReducer, {});
...
useEffect(() => {
...
hubConnection.on("ItemConcluido", mbtile => {
updateProcesso(mbtile, "ItemConcluido");
});
}, []);
const updateProcesso = (mbtileInfo, type) => {
if (mbtileInfo.processo === processoSetor.id)
dispatchSetor({ type, payload: mbtileInfo });
else if (mbtileInfo.processo === processoUsuario.id)
dispatchUsuario({ type, payload: mbtileInfo });
};
...
return (
<>
<MbTilesContainer processo={processoUsuario} />
<MbTilesContainer processo={processoSetor} />
</>
问题出在这一行:
if (mbtileInfo.processo === processoSetor.id)
"processoSetor" 始终为空。即使在 "ItemIniciado" 操作(省略代码)之前设置状态并呈现一切正常之后。
如果我评论这一行,一切都会继续呈现得很好。
所以我想知道我是否必须使用单个状态并在 de reducer 函数中进行这些检查,或者我做错了什么阻止我在渲染函数之外获取状态的实际值?
由于关闭而出现问题,因为您的 useEffect
仅在初始渲染时运行,当它订阅 hubConnection
时,它指的是在初始渲染时创建的 updateProcesso
函数当前词法范围指的是 reducer state 的初始值,它是一个空对象。当组件重新渲染时,这个函数被重新创建,而 hubConnection 回调仍然引用旧函数,它使用 reducer 状态的旧值。
要解决此问题,您必须将依赖项数组中的 processoSetor
和 processoUsuario
传递给 useEffect
,这是 useEffect
的第二个参数
useEffect(() => {
...
hubConnection.on("ItemConcluido", mbtile => {
updateProcesso(mbtile, "ItemConcluido");
});
}, [processoSetor, processoUsuario]);
我无法访问渲染函数之外的状态当前值。它总是return初始状态值
我有一个 signalR 连接,当我收到一条消息时,我想发送一个动作。 "problem" 是:我对两个状态对象使用相同的减速器。因此,我想检查一下我应该将 action 分派给哪一个。
减速器:
const processoReducer = (state, action) => {
switch (action.type) {
case "ProcessoIniciado":
return {...action.payload};
case "ItemIniciado":
return { ...state, iniciados: state.iniciados + 1 };
case "ItemConcluido":
case "ItemErro":
var arr = state.mbTiles.slice();
arr.pop();
return {
...state,
executados: state.executados + 1,
iniciados: state.iniciados - 1,
mbTiles: [action.payload, ...arr]
};
default:
return {...state};
}
};
组件:
const mbtiles = props => {
const [processoSetor, dispatchSetor] = useReducer(processoReducer, {});
const [processoUsuario, dispatchUsuario] = useReducer(processoReducer, {});
...
useEffect(() => {
...
hubConnection.on("ItemConcluido", mbtile => {
updateProcesso(mbtile, "ItemConcluido");
});
}, []);
const updateProcesso = (mbtileInfo, type) => {
if (mbtileInfo.processo === processoSetor.id)
dispatchSetor({ type, payload: mbtileInfo });
else if (mbtileInfo.processo === processoUsuario.id)
dispatchUsuario({ type, payload: mbtileInfo });
};
...
return (
<>
<MbTilesContainer processo={processoUsuario} />
<MbTilesContainer processo={processoSetor} />
</>
问题出在这一行:
if (mbtileInfo.processo === processoSetor.id)
"processoSetor" 始终为空。即使在 "ItemIniciado" 操作(省略代码)之前设置状态并呈现一切正常之后。
如果我评论这一行,一切都会继续呈现得很好。
所以我想知道我是否必须使用单个状态并在 de reducer 函数中进行这些检查,或者我做错了什么阻止我在渲染函数之外获取状态的实际值?
由于关闭而出现问题,因为您的 useEffect
仅在初始渲染时运行,当它订阅 hubConnection
时,它指的是在初始渲染时创建的 updateProcesso
函数当前词法范围指的是 reducer state 的初始值,它是一个空对象。当组件重新渲染时,这个函数被重新创建,而 hubConnection 回调仍然引用旧函数,它使用 reducer 状态的旧值。
要解决此问题,您必须将依赖项数组中的 processoSetor
和 processoUsuario
传递给 useEffect
,这是 useEffect
useEffect(() => {
...
hubConnection.on("ItemConcluido", mbtile => {
updateProcesso(mbtile, "ItemConcluido");
});
}, [processoSetor, processoUsuario]);