Hello guys.
I am struggling with some animation of a text in React. I want to animate opacity of a text from 0 to 1 when text changes. But problem is, that
element does not reload in React, when I change it’s text, so animation does not restart. It only works on reloading the page. I want it to restart animation, whenever I click a button. I am using newText property in state, so when the new text is selected, this property changes to true. I tryed with componentDidUpdate(), but this creates a infinite loop, because I am already setting new state on click of a button. Can you guys advise me on this problem?
Here is part of my code so far:
class QuoteBox extends React.Component {
constructor(props) {
super(props);
this.state = {
text: "",
author: "",
newText: false
};
//this.newQuote = this.newQuote.bind(this);
}
componentDidMount() {
this.newQuote();
}
componentDidUpdate() {
this.setAnimate();
}
newQuote = () => {
let randomQuote =
quotesCollection[Math.floor(Math.random() * quotesCollection.length)];
this.setState({
text: randomQuote.quote,
author: randomQuote.author,
newText: false
});
};
setAnimate = () => {
this.setState({
newText: true
});
}
tweetUrl = () => {
return 'https://twitter.com/intent/tweet?hashtags=quotes&related=freecodecamp&text=' + encodeURIComponent('"' + this.state.text + '" ' + this.state.author);
}
render() {
return (
<div>
<div id="box">
<p id="text" className={"quoteText " + (this.state.newText ? 'changeOpacity' : '')}><i className="fa fa-quote-left" /> {this.state.text}</p>
<p id="author" className={"authorText "}>- {this.state.author}</p>
</div>
<div className="buttons">
<button id="new-quote" className="button" onClick={this.newQuote}>New Quote</button>
<a id="tweet-quote" className="button" href={this.tweetUrl()} target="_blank">
<i className="fa fa-twitter" />
</a>
</div>
</div>
);
}
}
export default QuoteBox;
and CSS:
.quoteText {
font-size: 20pt;
i {
font-size: 1.5em;;
}
}
.authorText {
font-size: 15pt;
margin-top: 10px;
text-align: right;
}
.changeOpacity{
animation-name: bring-text;
animation-duration: 2s;
animation-fill-mode: forwards;
}
@keyframes bring-text {
from {
opacity: 0;
}
to {
opacity: 1;
}
}