Reputation: 165242
Consider the following simple React component with an effect that fetches some data and saves it to the component state:
function MyComponent(props) {
const [data, setData] = useState([]);
useEffect(() => {
const fetchData = async () => {
const res = await fetch("data.json");
setData(await res.json());
};
fetchData();
}, []);
return (
<></>
)
}
What is the right way to set this effect to run periodically, say every minute?
Is it as easy as replacing fetchData()
with setInterval(fetchData, 60)
or are there other React-specific considerations I should be thinking of?
Upvotes: 3
Views: 736
Reputation: 53884
Are there other React-specific considerations I should be thinking of?
Just for the completeness of Joseph's answer, you should consider memoizing the component's children, or it will rerender them on each interval:
// v Notice the children
function MyComponent({ children }) {
const [data, setData] = useState([]);
useEffect(() => {
const fetchData = async () => {
const res = await fetch('data.json');
setData(await res.json());
};
const interval = setInterval(fetchData, 60000);
return () => clearInterval(interval);
}, []);
// v Causes children to re-render every interval
return <>{children}</>;
}
export default MyComponent;
Possible case:
<MyComponent>
<Child />
</MyComponent>
Solution:
// Possible Child
function Child = () => <></>
// v Memoization using shallow comparison
export default React.memo(Child);
Upvotes: 2
Reputation: 12174
Is it as easy as replacing fetchData() with setInterval(fetchData, 60)
Yes.
Just make sure to do clearInterval
(return of useEffect()
) when component unmounts.
useEffect(() => {
const fetchData = async () => {
const res = await fetch("data.json");
setData(await res.json());
};
const t = setInterval(fetchData, 60000);
return () => clearInterval(t); // clear
}, []);
Upvotes: 5