3 回答
TA贡献1797条经验 获得超6个赞
afimport React, { useCallback, useState, useEffect, useRef } from "react";
import "./styles.css";
export default function App() {
let [count, setCount] = useState(0);
useInterval(() => {
setCount(count + 1);
}, 1000);
return <div className="App">{count}</div>;
}
function useInterval(callback, delay) {
const savedCallback = useRef();
// Remember the latest callback.
useEffect(() => {
savedCallback.current = callback;
}, [callback]);
// Set up the interval.
useEffect(() => {
function tick() {
savedCallback.current();
}
if (delay !== null) {
let id = setInterval(tick, delay);
return () => clearInterval(id);
}
}, [delay]);
}
工作代码沙箱
更新
正如 keith 建议的那样,不要将函数传递给数组 deps,如下所示。
import React, { useState, useEffect } from "react";
import "./styles.css";
export default function App() {
const [count, setCount] = useState(0);
useEffect(() => {
const interval = setInterval(() => {
setCount((count) => count + 1);
}, 1000);
return () => {
clearInterval(interval);
};
}, []);
return <div>{count}</div>;
}
TA贡献1802条经验 获得超10个赞
还是不太清楚为什么可以通过[]
也许需要更多解释,不幸的是评论太多,所以我发布了这个。
要回答这个问题,我们需要退一步,首先问,依赖数组的意义是什么?简单的答案是 useEffect 中任何依赖于某些内容的内容,如果从需要不同处理的 useState 或 Props 进行更改,则需要将其放入数组中。
例如,如果您有一个仅显示用户配置文件的组件,但获取此信息是异步的,因此需要 useEffect。它可能看起来像这样 ->
<UserProfile userId={userId}/>
现在的问题是,如果我们[]
作为依赖项传递,则 useEffect 不会为新的 userId 重新触发,因此 props 可能会说userId = 2
,但我们当前存储在状态中的数据是 for userId = 1
,.. 所以对于这样的东西[props.userId]
完全有道理。
那么回到 OP 的组件,<App/>
这里有什么会改变的?好吧,这不是道具,因为没有被传递。那么count
您可能会问,我们再次问自己这个问题,计数状态是否保证 setInterval 的新实例被销毁/创建?当然,这里的答案是否定的,因此[]
在这里传递是完全有意义的。
希望这是有道理的。
TA贡献1812条经验 获得超5个赞
清除卸载时的间隔
useEffect(() => {
let id;
const setId = () => {
id = setInterval(() => {
setCount((count) => count + 1);
}, 1000);
};
setId();
return () => clearInterval(id);
}, []);
添加回答
举报