我有一个包含行的表,每一行都有一个更新该行的操作按钮。
当我不使用React.memo时,一切正常。如果我将行组件放入 React.memo,在第一次更新时没问题,但下一次更新当前行,而上一个更新到初始状态。
我正在使用化简器来更新状态,当我控制台时.log状态它按预期更新。但是当我单击下一行的操作按钮时,作为起点,它使用上一个状态,然后将上一行返回到初始值。
似乎下一行中的操作按钮保留了对先前状态的引用,因为它没有重新渲染。
以下是代码的主要部分:
function reducer(state, action) {
switch (action.type) {
....
case 'update':
return { ...state, result: action.payload };
default:
throw new Error("Unknown state action");
}
}
const [state, dispatch] = useReducer(reducer, { loading: initialLoading, result: null });
const result = state.result;
const loading = state.loading;
// Called from the row action button
const handleUpdateResult = React.useCallback(index => data => {
// When called from the next row action button - result keeps old state, even component rendered row with new values
const newConnection = {
...result.connections[index],
status: data.status
};
const newConnections = [...result.connections.slice(0, index), newConnection, ...result.connections.slice(index + 1)];
const updatedResult = { ...result, connections: newConnections };
setResult(updatedResult);
}, [result, setResult]);
const setResult = useCallback((newState) => {
dispatch({ type: "update", payload: newState });
}, []);
任何想法我做错了什么:/...
也许有人会有同样的情况,所以我会解释问题和解决方案。
问题是handleUpdateResult
使用的是当前状态。在文档中的某个地方,我读到,每当您更新状态并且需要当前状态时,请使用 reducer。我实际上正在使用化简器,但我仍然在函数中使用了当前状态handleUpdateResult
这:)弄得一团糟。
无论如何,我没有在那里使用状态,而是向 reducer 发送一个操作来更新值,一切正常:
// Called from the row action button
const handleUpdateResult = React.useCallback((index, newStatus) => row => {
const newRow = {
...row,
status: newStatus
};
setResult({
action: "updateRow",
payload: {
index: index,
row: newRow
}
});
}, [setResult]);
当从函数中删除result
状态并从化简器中使用当前状态时,一切正常。更新行的逻辑将移动到化简器。