In react native app, there are two components A
and B
in App.js
which toggle with k
state change.
App.js
...
const App = () => {
const [ k, setK ] = useState(false);
const toggleK = () => setK(!k);
if(k) {
return <A />;
}else {
return <B toggleK={toggleK} />;
}
};
...
In A
, setInterval
is initialized in useffect
. It calls async function every 10 seconds. But when it unmounts on K
state change in App.js
, the cleaning function is not run (no A unmounting...
is logged) and so does the clearInterval
.
Any thing I'm doing wrong here?
...
const A = () => {
const [ someState, setSomeState ] = useState(...);
let timer;
useEffect(() => {
if(!timer) {
timer = setInterval(async () => await run_async_func(), 10000);
}
return () => {
console.log('A unmounting...');
clearInterval(timer);
};
}, [ someState ]);
};
...
Try this with useRef().
const A = () => {
const timer = useRef()
const [ someState, setSomeState ] = useState(...);
useEffect(() => {
if(!timer) {
timer.current = setInterval(async () => await run_async_func(), 10000);
}
return () => {
console.log('A unmounting...');
clearInterval(timer.current);
};
}, [ someState ]);
};
Resolved the issue
A. Overlooked the someState
in useEffect
dependency array. Basically, cleaner function will only run if any variable in dependency array mutates. So, I used another useEffect
without any dependencies (see below). Thanks @TayyabMazhar for pointing out this
...
const A = () => {
const [ someState, setSomeState ] = useState(...);
let timer;
useEffect(() => {
if(!timer) {
timer = setInterval(async () => await run_async_func(), 10000);
}
}, [ someState ]);
useEffect(() => {
return () => {
console.log('A unmounting...');
clearInterval(timer);
};
}, []);
};
...
you can use this hook i create this one
import { useEffect, useRef } from 'react';
export const useInterval = (callback: () => void, delay: number): void => {
const savedCallback = useRef(null);
// Remember the latest callback.
useEffect(() => {
savedCallback.current = callback;
}, [callback]);
// Set up the interval.
useEffect(() => {
function tick() {
savedCallback.current();
}
if (delay !== null) {
const id = setInterval(tick, delay);
return () => clearInterval(id);
}
}, [delay]);
};
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.