首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用useCallback进行无限更新循环(deps钩子/详尽-deps)

用useCallback进行无限更新循环(deps钩子/详尽-deps)
EN

Stack Overflow用户
提问于 2020-01-29 03:59:53
回答 1查看 201关注 0票数 0

考虑下面的示例,该示例呈现iframe的列表。

我想将呈现的iframes的所有iframe存储在frames中。

代码语言:javascript
复制
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>
  );
}

这里有两个问题:

  1. react-hooks/exhaustive-deps正在抱怨依赖数组中缺少setDocument。但是,添加它会导致无限更新循环。
  2. 控制台日志记录frames显示,只设置了移动的document。我希望桌面的document也会被设置。

你要怎么解决这个问题?

码箱

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-01-29 04:54:08

代码语言:javascript
复制
const setFrameDocument = useCallback(
    (id, document) => setFrames((frames) => ({
      ...frames,
      [id]: {
        ...frames[id],
        document
      }
    })),
    []
  );

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

由于状态的更新,框架对象的引用不断变化。对于前面的实现(即依赖数组中的frames对象),它将引起连锁反应,从而导致组件重新呈现,并导致frames对象获得新的引用。这会永远持续下去。

仅使用setFrames函数(一个常量引用),这个链反应就不会传播。eslint知道setFrames是一个常量引用,所以它不会向用户抱怨依赖数组中缺少它。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59960307

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档