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
});
}
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
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;
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
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()
.
CodePudding user response:
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
CodePudding user response:
You can approach to children of an 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>
);
}
}
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>