Reputation: 61
I am trying to clear the useInterval
function once the joke
array has 5 jokes as objects. However, I'm not sure what I'm doing wrong. For full code: https://codesandbox.io/s/asynchronous-test-mp2fq?file=/AutoComplete.js
const [joke, setJoke] = React.useState([]);
function useInterval(callback, delay) {
const savedCallback = useRef();
let id;
useEffect(() => {
savedCallback.current = callback;
if (joke.length === 5) {
console.log("5 STORED AND CLEARED INTERVAL");
return () => clearInterval(id);
}
});
useEffect(() => {
function tick() {
savedCallback.current();
}
id = setInterval(tick, delay);
return () => clearInterval(id);
}, [delay]);
}
useInterval(() => {
// setJoke(joke);
axios.get("https://api.chucknorris.io/jokes/random").then((res) => {
setJoke(joke.concat(res.data.value));
console.log("JOKE: ", joke);
});
console.log("Every 5 seconds");
}, 5000);
Upvotes: 0
Views: 849
Reputation: 191976
Use a ref to store the interval id, to preserve it between re-renders. When the length is 5, call clearInterval
instead of returning a clean function that would be called when the component unmounts.
In addition, make the hook agnostic of the actual stop condition by supplying a stop
function, and calling it whenever the component re-renders.
function useInterval(callback, delay, stop) {
const savedCallback = useRef();
const interval = useRef();
useEffect(() => {
savedCallback.current = callback;
if (stop?.()) { // call stop to check if you need to clear the interval
clearInterval(interval.current); // call clearInterval
}
});
useEffect(() => {
function tick() {
savedCallback.current();
}
interval.current = setInterval(tick, delay); // set the current interval id to the ref
return () => clearInterval(interval.current);
}, [delay]);
}
const Example () => {
const [joke, setJoke] = React.useState([]);
useInterval(() => {
// setJoke(joke);
axios.get("https://api.chucknorris.io/jokes/random").then((res) => {
setJoke(joke.concat(res.data.value));
console.log("JOKE: ", joke);
});
console.log("Every 5 seconds");
}, 5000, () => joke.length > 4);
return (
...
);
};
Upvotes: 2
Reputation: 387
Try adding in callback
to your dependency array
useEffect(() => {
savedCallback.current = callback;
if (joke.length === 5) {
console.log("5 STORED AND CLEARED INTERVAL");
return () => clearInterval(id);
}
},[callback]);
Upvotes: 0