I’m learning React and having trouble with component lifecycle, or some kind of memory leak. In the code below I’ve using [this codepen][1] in React, and it works, until my Preloader unmounts, and I continually get error below.
Is this a place for a cleanup function? How do I stop animate() from firing after the Preloader has been removed from the dom?
Error
"Uncaught TypeError: text2.current is null
setMorph Preloader.jsx:47
doMorph Preloader.jsx:42
animate Preloader.jsx:83"
In Parent Component
const { initialLoad, setInitialLoad } = useGlobalState();
useEffect(() => {
if (initialLoad) {
setTimeout(() => {
setInitialLoad(false);
}, 4600);
}
}, [initialLoad]);
return (
<div className='browser-wrapper'>
{initialLoad &&
<Preloader initialLoad={initialLoad} />
}
...
)
Preloader Component
const Preloader = ({ initialLoad }) => {
const text1 = useRef(null)
const text2 = useRef(null)
// Insert Text String and Morph tuning adjusments
const morphTime = .68;
const cooldownTime = 0.12;
let textIndex = texts.length - 1;
let time = new Date();
let morph = 0;
let cooldown = cooldownTime;
text1.current = texts[textIndex % texts.length];
text2.current = texts[(textIndex + 1) % texts.length];
function doMorph() {
morph -= cooldown;
cooldown = 0;
let fraction = morph / morphTime;
if (fraction > 1) {
cooldown = cooldownTime;
fraction = 1;
}
setMorph(fraction);
}
// A lot of the magic happens here, this is what applies the blur filter to the text.
function setMorph(fraction) {
text2.current.style.filter = `blur(${Math.min(8 / fraction - 8, 100)}px)`;
text2.current.style.opacity = `${Math.pow(fraction, 0.4) * 100}%`;
fraction = 1 - fraction;
text1.current.style.filter = `blur(${Math.min(8 / fraction - 8, 100)}px)`;
text1.current.style.opacity = `${Math.pow(fraction, 0.4) * 100}%`;
text1.current.textContent = texts[textIndex % texts.length];
text2.current.textContent = texts[(textIndex + 1) % texts.length];
}
function doCooldown() {
morph = 0;
text2.current.style.filter = "";
text2.current.style.opacity = "100%";
text1.current.style.filter = "";
text1.current.style.opacity = "0%";
}
// Animation loop, which is called every frame.
function animate() {
requestAnimationFrame(animate);
let newTime = new Date();
let shouldIncrementIndex = cooldown > 0;
let dt = (newTime - time) / 1000;
time = newTime;
cooldown -= dt;
if (cooldown <= 0) {
if (shouldIncrementIndex) {
textIndex++;
}
doMorph();
} else {
doCooldown();
}
}
useEffect(() => {
if (text2.current !== null || undefined) {
animate();
} else {
console.log('current text.2 is ' + text2.current)
}
}, [text2.current])
return ( --- JSX follows
```
[1]: https://codepen.io/Valgo/pen/PowZaNY?ref=devawesome.io