【问题标题】:setting state inside useEffect在 useEffect 中设置状态
【发布时间】:2021-03-26 15:53:54
【问题描述】:

我正在尝试更新 useEffect 中的状态 (tableColumnConfiguration),然后将该状态传递给子组件,但是此代码会引发“超出最大更新深度”错误,并且应用程序冻结而无法点击屏幕上的任何内容。

const[environmentTableColumns, setEnvironmentTableCoulmns] = useState(environmentConditionsColumns);

const {
  data: conditionTypeData,
  loading: loadingConditionTypeData,
  errorRedirect: conditionTypeDataErrorRedirect
} = useSectionEnumQuery('conditionType'); // this is API call


useEffect(() => {
  if (conditionTypeData) {
    let data; 
    let updatedEnvironmentColumnConfiguration = environmentConditionsColumns;
    updatedEnvironmentColumnConfiguration = updatedEnvironmentColumnConfiguration.map(item => {
      if (item.dataIndex === 'conditionType') {
        data = conditionTypeData;
      }
      return data
        ? {
          ...item,
          render: text => {
            return renderEnum(text, data);
          }
        }
        : item;
    });
    setEnvironmentTableCoulmns(updatedEnvironmentColumnConfiguration); // here i am setting the state 
  }
}, [conditionTypeData])

子组件:

<SpaceTypeTable
  values={values}
  isReadOnly={isReadOnly}
  isProjectSystem={isProjectSystem}
  tableTitle="Environment Criteria"
  mappedLibrarySourceArray="environments"
  sourceRender={p => renderGuidelineItem(p, true)}
  tableColumns={environmentTableColumns} // here i am passing the column configuration
  section={MASTER_SECTIONS.LIBRARY_ENVIRONMENT}
  guidelines={guidelines}
  form={form}
  handleWarning={handleWarning}
/>

是什么导致了这个useEffect 循环?

更新:UseSectionEnumQuery

export const useSectionEnumQuery = resultFieldName => {
  const { data: result, loading, error } = useQuery(ENUM_TYPES(resultFieldName));
  const data = result?.[resultFieldName] && sortBy(result[resultFieldName], o => o.label);
  const errorRedirect = error && errorRedirectElement(error, resultFieldName);
  return { loading, data, errorRedirect };
};

【问题讨论】:

  • 它发生在哪里并不一定很明显,但在这种情况下,它几乎总是在 useeffect 中设置状态触发重新渲染,从而导致效果再次运行,从而再次设置状态等等。
  • 正是因为那个useeffect我得到了上面的错误
  • 是的,这就是我要说的。如果你在 useEffect 处理程序中设置了一个状态,该状态处理程序在其依赖数组中具有,即使是间接的,它也会在无限渲染循环中运行。
  • 我将 api 结果作为 useeffect 的依赖项
  • conditionTypeData 可能正在为每个渲染创建一个新引用,并且由于它是您的 useEffect 中的一个依赖项,因此会导致循环。我们可以看看你的useSectionEnumQuery 钩子吗?

标签: javascript reactjs react-hooks use-state


【解决方案1】:

这条线导致了你的问题。

const data = result?.[resultFieldName] &amp;&amp; sortBy(result[resultFieldName], o =&gt; o.label);

data 将是每次渲染的新引用,它会触发您的 useEffect 每次渲染,因为 dataconditionTypeData 并且它在您的依赖项中。

你能不能尝试记忆这个值,所以它只有在结果改变时才会改变。

export const useSectionEnumQuery = resultFieldName => {
  const { data: result, loading, error } = useQuery(ENUM_TYPES(resultFieldName));
  const data = useMemo(() => result?.[resultFieldName] && sortBy(result[resultFieldName], o => o.label), [result, resultFieldName]);
  const errorRedirect = useMemo(() => error && errorRedirectElement(error, resultFieldName), [error, resultFieldName]);
  return { loading, data, errorRedirect };
};

【讨论】:

  • 能否请您告诉我如何解决这个问题,但 useSectionEnumQuery 在很多地方都使用过
  • @EnigmaState 用 usememo 记忆它
  • 更新了一个潜在的解决方案
猜你喜欢
  • 2020-08-26
  • 2021-08-30
  • 1970-01-01
  • 2019-11-01
  • 2021-02-11
  • 2021-10-17
  • 2022-01-21
  • 2020-05-23
  • 1970-01-01
相关资源
最近更新 更多