如何使用 useEffect 挂钩定期获取请求?
How to fetch request in regular intervals using the useEffect hook?
我想做的是每 5 秒从一个随机引用 API 中获取一个随机引用,并将其内容设置为 React 组件。
我能够成功获取请求并显示其内容,但是在 运行 setInterval 方法与获取方法 fetchQuote
和 5 秒间隔之后,内容在该间隔内更新多次。
import { Badge, Box, Text, VStack, Container} from '@chakra-ui/react';
import React, { useState, useEffect } from 'react';
import axios from 'axios';
const RandomQuotes = () => {
const [quote, setQuote] = useState<Quote>(quoteObject);
const [error, setError]: [string, (error: string) => void] = React.useState("");
const [loading, setLoading] = useState(true);
const fetchQuote = () => {
axios.get<Quote>(randomQuoteURL)
.then(response => {
setLoading(false);
setQuote(response.data);
})
.catch(ex => {
setError(ex);
console.log(ex)
});
}
setInterval(() => setLoading(true), 5000);
useEffect(fetchQuote, [loading, error]);
const { id, content, author } = quote;
return (
<>
<RandomQuote
quoteID={id}
quoteContent={content}
quoteAuthor={author}
/>
</>
);
}
当任何状态或道具值更新时,您的函数体将 re-run,称为 re-render。
并且你已经在主函数中调用了 setInterval
(!!!),所以每次组件 re-renders,它都会一次又一次地创建另一个间隔。您的浏览器将在几分钟后卡住。
你需要这个间隔定义一次,这就是useEffect
第二个参数为空的目的。
此外,使用 loading
标志作为 API 调用的触发器是可行的,但在语义上没有任何意义,而且观察者非常昂贵且不需要。
这是一个大致正确的例子:
useEffect(() => {
const myInterval = setInterval(fetchQuote, 5000);
return () => {
// should clear the interval when the component unmounts
clearInterval(myInterval);
};
}, []);
const fetchQuote = () => {
setLoading(true);
// your current code
};
我想做的是每 5 秒从一个随机引用 API 中获取一个随机引用,并将其内容设置为 React 组件。
我能够成功获取请求并显示其内容,但是在 运行 setInterval 方法与获取方法 fetchQuote
和 5 秒间隔之后,内容在该间隔内更新多次。
import { Badge, Box, Text, VStack, Container} from '@chakra-ui/react';
import React, { useState, useEffect } from 'react';
import axios from 'axios';
const RandomQuotes = () => {
const [quote, setQuote] = useState<Quote>(quoteObject);
const [error, setError]: [string, (error: string) => void] = React.useState("");
const [loading, setLoading] = useState(true);
const fetchQuote = () => {
axios.get<Quote>(randomQuoteURL)
.then(response => {
setLoading(false);
setQuote(response.data);
})
.catch(ex => {
setError(ex);
console.log(ex)
});
}
setInterval(() => setLoading(true), 5000);
useEffect(fetchQuote, [loading, error]);
const { id, content, author } = quote;
return (
<>
<RandomQuote
quoteID={id}
quoteContent={content}
quoteAuthor={author}
/>
</>
);
}
当任何状态或道具值更新时,您的函数体将 re-run,称为 re-render。
并且你已经在主函数中调用了 setInterval
(!!!),所以每次组件 re-renders,它都会一次又一次地创建另一个间隔。您的浏览器将在几分钟后卡住。
你需要这个间隔定义一次,这就是useEffect
第二个参数为空的目的。
此外,使用 loading
标志作为 API 调用的触发器是可行的,但在语义上没有任何意义,而且观察者非常昂贵且不需要。
这是一个大致正确的例子:
useEffect(() => {
const myInterval = setInterval(fetchQuote, 5000);
return () => {
// should clear the interval when the component unmounts
clearInterval(myInterval);
};
}, []);
const fetchQuote = () => {
setLoading(true);
// your current code
};