简体   繁体   English

使用 useCallback 响应无限更新循环(react-hooks/exhaustive-deps)

[英]React infinite update loop with useCallback (react-hooks/exhaustive-deps)

Consider the following example that renders a list of iframe s.考虑以下呈现iframe列表的示例。

I'd like to store all the document s of the rendered iframe s in frames .我想将渲染的iframe的所有document存储在frames

import React, { useState, useEffect, useCallback } from "react";
import Frame, { FrameContextConsumer } from "react-frame-component";

function MyFrame({ id, document, setDocument }) {
  useEffect(() => {
    console.log(`Setting the document for ${id}`);
    setDocument(id, document);
  }, [id, document]); // Caution: Adding `setDocument` to the array causes an infinite update loop!

  return <h1>{id}</h1>;
}

export default function App() {
  const [frames, setFrames] = useState({
    desktop: {
      name: "Desktop"
    },
    mobile: {
      name: "Mobile"
    }
  });
  const setFrameDocument = useCallback(
    (id, document) => {
      setFrames({
        ...frames,
        [id]: {
          ...frames[id],
          document
        }
      });
    },
    [frames, setFrames]
  );

  console.log(frames);

  return (
    <div className="App">
      {Object.keys(frames).map(id => (
        <Frame key={id}>
          <FrameContextConsumer>
            {({ document }) => (
              <MyFrame
                id={id}
                document={document}
                setDocument={setFrameDocument}
              />
            )}
          </FrameContextConsumer>
        </Frame>
      ))}
    </div>
  );
}

There are two issues here:这里有两个问题:

  1. react-hooks/exhaustive-deps is complaining that setDocument is missing in the dependency array. react-hooks/exhaustive-deps抱怨依赖数组中缺少setDocument But, adding it causing an infinite update loop.但是,添加它会导致无限更新循环。
  2. Console logging frames shows that only mobile's document was set.控制台日志frames显示只设置了移动设备的document I expect desktop's document to be set as well.我希望桌面的document也能设置。

How would you fix this?你会如何解决这个问题?

Codesandbox代码沙盒

const setFrameDocument = useCallback(
    (id, document) => setFrames((frames) => ({
      ...frames,
      [id]: {
        ...frames[id],
        document
      }
    })),
    []
  );

https://codesandbox.io/s/gracious-wright-y8esd https://codesandbox.io/s/gracious-wright-y8esd


The frames object's reference keeps changing due to the state's update.由于状态的更新,frames 对象的引用不断变化。 With the previous implementation (ie the frames object within the dependency array), it would cause a chain reaction that would cause the component to re-render and causing the frames object getting a new reference.使用之前的实现(即依赖数组中的frames 对象),它会引起连锁反应,导致组件重新渲染并导致frames 对象获得新的引用。 This would go on forever.这将永远持续下去。

Using only setFrames function (a constant reference), this chain react won't propagate.仅使用 setFrames 函数(常量引用),此链式反应不会传播。 eslint knows setFrames is a constant reference so it won't complain to the user about it missing from the dependency array. eslint 知道 setFrames 是一个常量引用,因此它不会向用户抱怨它从依赖项数组中丢失。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 react-hooks/exhaustive-deps 警告还是无限循环? - react-hooks/exhaustive-deps warning or infinite loop? useCallBack react-hooks/exhaustive-deps 警告 - useCallBack react-hooks/exhaustive-deps warning 遵守 react-hooks/exhaustive-deps 会导致无限循环和/或大量 useCallback() - Obeying react-hooks/exhaustive-deps leads to infinite loops and/or lots of useCallback() react-hooks/exhaustive-deps 警告 - react-hooks/exhaustive-deps warning 由 axios 取消令牌引起的 react useEffect hook 无限循环 [react-hooks/exhaustive-deps] - react useEffect hook infinite loop caused by axios cancel token [react-hooks/exhaustive-deps] ESLint 希望 setSate 作为 useEffect 的依赖,但这会导致无限循环(react-hooks/exhaustive-deps) - ESLint wants setSate as a dependency for useEffect but this causes an infinite loop (react-hooks/exhaustive-deps) React挂钩:如何使用react-hooks / exhaustive-deps规则在没有无限循环的情况下读取和更新挂钩中的状态 - React hooks: How to read & update state in hooks without infinite loops with react-hooks/exhaustive-deps rule 是否可以通过 useCallback 避免自定义 React Hook 上的“eslint(react-hooks/exhaustive-deps)”错误? - Is it possible to avoid 'eslint(react-hooks/exhaustive-deps)' error on custom React Hook with useCallback? React Hooks Exhaustive-deps 异步无限循环 - React Hooks Exhaustive-deps async infinite Loop 反应 useEffect 带有警告的钩子 react-hooks/exhaustive-deps - React useEffect hook with warning react-hooks/exhaustive-deps
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM