Ill*_*nko 5 javascript setinterval reactjs react-hooks use-effect
我需要定期获取数据并将其更新到屏幕上。我有这个代码:
const [temperature, setTemperature] = useState();
useEffect(() => {
fetch("urlToWeatherData")
.then(function(response) {
if (response.status !== 200) {
console.log(
"Looks like there was a problem. Status Code: " + response.status
);
return;
response.json().then(function(data) {
console.log(data[0].temperature);
setTemperature(data[0].temperature);
});
})
.catch(function(err) {
console.log("Fetch Error :-S", err);
});
}, [] );
Run Code Online (Sandbox Code Playgroud)
那么,例如,有没有什么巧妙的方法可以每 15 秒运行一次?谢谢!
Nic*_*wer 10
把它包裹在一个区间内,不要忘记在组件卸载时返回一个teardown函数来取消这个区间:
useEffect(() => {
const id = setInterval(() =>
fetch("urlToWeatherData")
.then(function(response) {
if (response.status !== 200) {
console.log(
"Looks like there was a problem. Status Code: " + response.status
);
return;
response.json().then(function(data) {
console.log(data[0].temperature);
setTemperature(data[0].temperature);
});
})
.catch(function(err) {
console.log("Fetch Error :-S", err);
});
), 15000);
return () => clearInterval(id);
}, []);
Run Code Online (Sandbox Code Playgroud)
只是为了提供不同的方法,您可以定义一个自定义挂钩来将此功能提取到可重用的函数中:
const useInterval = (callback, interval, immediate) => {
const ref = useRef();
// keep reference to callback without restarting the interval
useEffect(() => {
ref.current = callback;
}, [callback]);
useEffect(() => {
// when this flag is set, closure is stale
let cancelled = false;
// wrap callback to pass isCancelled getter as an argument
const fn = () => {
ref.current(() => cancelled);
};
// set interval and run immediately if requested
const id = setInterval(fn, interval);
if (immediate) fn();
// define cleanup logic that runs
// when component is unmounting
// or when or interval or immediate have changed
return () => {
cancelled = true;
clearInterval(id);
};
}, [interval, immediate]);
};
Run Code Online (Sandbox Code Playgroud)
然后你可以像这样使用钩子:
const [temperature, setTemperature] = useState();
useInterval(async (isCancelled) => {
try {
const response = await fetch('urlToWeatherData');
// check for cancellation after each await
// to prevent further action on a stale closure
if (isCancelled()) return;
if (response.status !== 200) {
// throw here to handle errors in catch block
throw new Error(response.statusText);
}
const [{ temperature }] = await response.json();
if (isCancelled()) return;
console.log(temperature);
setTemperature(temperature);
} catch (err) {
console.log('Fetch Error:', err);
}
}, 15000, true);
Run Code Online (Sandbox Code Playgroud)
setTemperature()如果组件被卸载,我们可以通过检查来阻止回调的调用isCancelled()。useInterval()对于回调依赖于有状态变量的更一般用例,您应该更喜欢或至少useReducer()使用.useState()
| 归档时间: |
|
| 查看次数: |
2786 次 |
| 最近记录: |