【发布时间】:2021-06-24 16:39:14
【问题描述】:
我遇到了一个无法找到答案的钩子问题。最接近的文章是this other post。
本质上,我希望有一个函数,它在每个组件生命周期中使用钩子调用一次。我通常会这样使用useEffect:
useEffect(() => {
doSomethingOnce()
setInterval(doSomethingOften, 1000)
}, [])
我正在尝试不禁用 eslint 规则并收到 react-hooks/exhaustive-deps 警告。
将此代码更改为以下代码会产生一个问题,即每次呈现组件时都会调用我的函数...我不想要这个。
useEffect(() => {
doSomethingOnce()
setInterval(doSomethingOften, 1000)
}, [doSomethingOnce])
建议的解决方案是将我的函数包装在 useCallback 中,但我找不到答案是如果 doSomethingOnce 取决于状态。
下面是我想要实现的最小代码示例:
import "./styles.css";
import { useEffect, useState, useCallback } from "react";
export default function App() {
const [count, setCount] = useState(0);
const getRandomNumber = useCallback(
() => Math.floor(Math.random() * 1000),
[]
);
const startCounterWithARandomNumber = useCallback(() => {
setCount(getRandomNumber());
}, [setCount, getRandomNumber]);
const incrementCounter = useCallback(() => {
setCount(count + 1);
}, [count, setCount]);
useEffect(() => {
startCounterWithARandomNumber();
setInterval(incrementCounter, 1000);
}, [startCounterWithARandomNumber, incrementCounter]);
return (
<div className="App">
<h1>Counter {count}</h1>
</div>
);
}
正如您从this demo 看到的那样,因为incrementCounter 依赖于count,它会被重新创建。这反过来又重新调用了我只想被调用一次的useEffect 回调。结果是startCounterWithARandomNumber 和incrementCounter 被调用的次数比我预期的要多。
任何帮助将不胜感激。
更新
我应该指出,这是一个实际用例的最小示例,其中事件是异步的。
在我的真实代码中,上下文是一个实时转录应用程序。我最初对 GET /api/all.json 进行 fetch 调用以获取整个转录,然后每秒轮询 GET /api/latest.json,将最新的语音与当前状态的文本合并。我试图在我的最小示例中模拟这一点,种子开始,然后是一个依赖于当前状态的轮询方法调用。
【问题讨论】:
标签: javascript reactjs react-hooks