具有状态依赖性的 useCallback 会导致无限循环

useCallback with state dependency causes infinite loop

我有一个更新状态的 useCallback,但是因为它需要将该状态作为依赖项,所以它在更新状态时创建了一个无限循环。我在这里使用 useImmer,但在使用普通 useState 时也会发生这种情况。

const [panels, updatePanels] = useImmer({
    activePanel: 0,
    validPanels: [],
});
const onValidatePanel = useCallback(isValid => {
    const panelIndex = panels.validPanels.indexOf(panels.activePanel);

    // Add
    if (panelIndex === -1 && isValid) {
        updatePanels(draft => {
            draft.validPanels.push(draft.activePanel);
        });
    // Remove
    } else if (panelIndex > -1 && !isValid) {
        updatePanels(draft => {
            draft.validPanels.splice(panelIndex, 1);
        });
    }
}, [panels]);

基本上当添加或删除索引时,panels 发生变化,再次触发 onValidatePanel,然后重新添加索引,如此等等……

我该如何解决这个问题?

我认为您根本不需要填充依赖项数组,您可以从功能状态更新程序函数中的 draft 副本访问 panels 状态。

const onValidatePanel = useCallback(isValid => {
  updatePanels(draft => {
    const panelIndex = draft.validPanels.indexOf(draft.activePanel);

    if (panelIndex === -1 && isValid) {
      // Add
      draft.validPanels.push(draft.activePanel);
    } else if (panelIndex > -1 && !isValid) {
      // Remove
      draft.validPanels.splice(panelIndex, 1);
    }
  });
}, []);