I have the a React component called Hero. I'm using the anime.js lib to add some effects to my title.
My animations are stored in a file called animations.js which looks like this:
import anime from 'animejs/lib/anime.es.js';
export function letterStagger(){
console.log("test");
var textWrapper = document.querySelector('.hero__title .hero__title-letters');
console.log(textWrapper); // returns null
textWrapper.innerHTML = textWrapper.textContent.replace(/\S/g, "<span class='hero__title-letter'>$&</span>");
anime.timeline({loop: true})
.add({
targets: '.hero__title .hero__title-letter',
translateY: ["1.1em", 0],
translateZ: 0,
duration: 750,
delay: (el, i) => 50 * i
}).add({
targets: '.hero__title',
opacity: 0,
duration: 1000,
easing: "easeOutExpo",
delay: 1000
});
}
Now, I'm trying to run this function in my Hero component, like so:
import React from 'react';
import { letterStagger } from "../../utils/animations";
class Hero extends React.Component{
render(){
return (
<section className="hero">
<h1 className="hero__title">
<span className="hero__title-inner">
<span className="hero__title-letters">This is the title</span>
</span>
</h1>
</section>
)
letterStagger();
}
}
export default Hero;
I have no compilation errors, but I have a warning which says Unreachable code on letterStagger().
If I have letterStagger() after render() I get errors in relation to textContent. When I run console.log(textWrapper);, it returns null, which makes me think the function is running before the text is found (which is why I've tried adding letterStagger() at the end of render().
You shouldn’t manipulate DOM directly in React, it can lead to unexpected behavior. Use refs instead https://reactjs.org/docs/refs-and-the-dom.html
You can approach to children of a Component only when the component has been mounted. It means, you should use a method of the Component's life cycle. In your case it is componentDidMount
So the working code will be as follows:
class Hero extends React.Component {
componentDidMount() {
letterStagger();
}
render() {
return (
<section className="hero">
<h1 className="hero__title">
<span className="hero__title-inner">
<span className="hero__title-letters">This is the title</span>
</span>
</h1>
</section>
);
}
}