【发布时间】:2019-01-09 02:50:21
【问题描述】:
useEffect、useMemo、useCallback 等一些 React Hooks API 有第二个参数:输入数组:
useEffect(didUpdate, inputs);
正如官方文档所说:
@见Conditionally firing an effect
这样,如果其中一个输入发生变化,总是会重新创建效果。
在效果函数中引用的每个值也应该出现在输入数组中。
所以我们可以看到,inputs 数组有两个职责。
在大多数情况下,它们工作正常。但有时它们会发生冲突。
例如,我有一个小程序,它做了两件事:
点击按钮,计数加1。
每 5 秒将计数发送到服务器。
代码沙盒:
https://codesandbox.io/s/k0m1mq9v
或者在这里查看代码:
import { useState, useEffect, useCallback } from 'react';
function xhr(count) {
console.log(`Sending "${count}" to my server.`);
// TODO send count to my server by XMLHttpRequest
}
function add1(n) {
return n + 1;
}
function Example() {
// Declare a new state variable, which we'll call "count"
const [count, setCount] = useState(0);
// Handle click to increase count by 1
const handleClick = useCallback(
() => setCount(add1),
[],
);
// Send count to server every 5 seconds
useEffect(() => {
const intervalId = setInterval(() => xhr(count), 5000);
return () => clearInterval(intervalId);
}, []);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={handleClick}>
Click me
</button>
</div>
);
}
export default Example;
当我运行这段代码时,我总是将count = 0 发送到我的服务器,因为我还没有将count 传递给useEffect。
但是如果我将count 传递给useEffect,我的setInterval 将被清除,并且每次单击按钮时都会重新创建整个回调。
我认为也许还有另一种范式来实现我没有想到的目标。如果不是,那就是inputs数组的冲突。
【问题讨论】:
-
你这里的场景绝对是有效的,虽然我发现它相当特定于
setInterval函数的特性,也许还有 limitation 只能从 React 函数调用钩子。 -
@ClaireLin
setInterval只是一个例子。WebSocket、setTimeout、addEventListener、XMLHttpRequest等,他们都有同样的问题。
标签: javascript reactjs react-hooks