Javascript 反应挂钩。周期运行效应
我需要定期获取数据并将其更新到屏幕上。 我有以下代码:Javascript 反应挂钩。周期运行效应,javascript,reactjs,react-hooks,setinterval,use-effect,Javascript,Reactjs,React Hooks,Setinterval,Use Effect,我需要定期获取数据并将其更新到屏幕上。 我有以下代码: const [temperature, setTemperature] = useState(); useEffect(() => { fetch("urlToWeatherData") .then(function(response) { if (response.status !== 200) { console.log( "Looks like there was a problem
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);
});
}, [] );
那么,在这个例子中,是否有任何简洁的方法可以每15秒运行一次呢?
谢谢 将其包装成一个间隔,并且不要忘记在组件卸载时返回一个拆卸函数来取消间隔:
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);
}, []);
为了提供一种不同的方法,您可以定义一个自定义挂钩,用于将此功能提取到可重用函数中:
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]);
};
然后你可以像这样使用钩子:
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);
如果通过检查
isCancelled()
卸载组件,我们可以防止回调调用setTemperature()
。对于回调依赖于有状态变量时的useInterval()
更一般的用例,您应该更喜欢或至少使用。只是一个补充说明,如果您想在初始化后立即运行它,而不是15秒,只需命名arrow函数,将引用传递给setInterval()
然后在返回拆卸前立即呼叫。谢谢大家!我将它包装在一个函数中,然后只调用了两次,比如:getData()代码>设置间隔(getData,15000)代码>现在它似乎完全按照它应该的方式工作。