我如何在没有无限循环的情况下使用useEffect中的扩散操作符?



我编写了一个Chrome扩展。在React中,pop .html的实现如下:

const [blogUrls, setblogUrls] = useState<string[]>([]);
useEffect(() => {
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
const newBlogUrls = [...blogUrls, ...request.param.blogUrls];
setblogUrls(newBlogUrls);
return true;
});
}, [blogUrls]);

如何避免无限循环?

虽然我写了setblogUrls(newBlogUrls),但我知道写[blogUrls]不好。

但我想写得像[...blogUrls,

请告诉我如何解决这个矛盾。

试试这个-

useEffect(() => {
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
const newBlogUrls = [...blogUrls, ...request.param.blogUrls];
setblogUrls(newBlogUrls);
return true;
});
return () => chrome.runtime.onMessage.removeEventListener();
}, []);

它将在页面呈现后执行一次。你的依赖项blogUrls在useEffect本身渲染页面后改变。所以useEffect一次又一次地调用自己。这样就形成了无限循环。要渲染一次,只需确保useEffect中的dependency为空。

  1. 您的代码在每次渲染时添加一个侦听器。
// runs on every render
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
  1. Remove listener as -
const [blogUrls, setblogUrls] = useState<string[]>([]);
function onBlogUrlsChanged(request) {
const newBlogUrls = [...blogUrls, ...request.param.blogUrls];
setblogUrls(newBlogUrls);
}
useEffect(() => {
chrome.runtime.onConnect.addListener(onBlogUrlsChanged);
return () => {
chrome.runtime.onConnect.removeListener(onBlogUrlsChanged);
}
}, []);

可以通过传递[]参数只运行一次useEffect。,我们不会在每次重新渲染组件时都浪费地附加和分离侦听器。

你可以这样做

useEffect(() => {
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
setblogUrls((v) => [...v, ...request.param.blogUrls]);
return true;
});
// Don't forget to clean the listener
return () => chrome.runtime.onMessage.removeEventListener()
}, []);

最新更新