React infinite update loop with useCallback (react-hooks/exh



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

我想将渲染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>
);
}

这里有两个问题:

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

您将如何解决这个问题?

代码沙盒

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

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


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

仅使用 setFrames 函数(常量引用(,此链反应不会传播。 eslint 知道 setFrame 是一个常量引用,因此它不会向用户抱怨它从依赖数组中丢失。

相关内容

  • 没有找到相关文章

最新更新