0

我有一个带有行的表,每一行都有一个更新该行的操作按钮。

当我不使用 React.memo 时,一切正常。如果我将 rows 组件放入 React.memo,第一次更新就可以了,但下一个更新当前行,而前一个返回到初始状态。

我正在使用 reducer 来更新状态,当我使用 console.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 });
}, []);

任何想法我做错了什么:/ ...

4

1 回答 1

0

也许有人会有同样的情况,所以我将解释问题和解决方案。

问题是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从函数中删除状态并从减速器中使用当前状态时,一切正常。更新行的逻辑被移到reducer。

于 2020-07-06T12:09:43.753 回答