So, my problem is that I have a component, I associated an animation to it and it is working when the component is rendered for the first time, but on an event click I change some conditions and some props associated to this component, But my element is not re rendered, it is just changing what has been changed, that means that the element is not removed from the dom et added to the DOM again, that's why I am not able to see the animation again, so it is not re-rendered or I just did not get what re render means.
I tried some solutions of course, but I am stuck, I tried to use this method :
this.forceUpdate();
But again, I am still not getting anything.
I dont think I have to write the whole code I wrote, becuase it is a lot and includes many other things but This is what I think is needed.
methodWillReceiveProps in my component :
componentWillReceiveProps(props) {
if (props.isRerendered) {
this.forceUpdate();
}
}
props.isRendered is returning true everytime, I checked with some console.log methods.
This is what is rendered :
render() {
return (
<div
className={cs({
"tls-forms": true,
"tls-forms--large": this.props.type === "S",
"tls-forms--medium tls-forms--login": !(this.props.type === "S")
})}
>
// content here
</div>);
}
And here is the sass file and the simple fading animation :
.tls-forms {
animation: formFading 3s;
// childs properties here
}
@keyframes formFading {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
I will really appreciate any help given.
You could make use of keys that react is using to determine whether something has changed. This means that your render method should look something like this:
import shortid from "shortid";
getRandomKey = () => {
return shortid.generate();
}
render() {
return (
<div
key={this.getRandomKey()}
className={cs({
"tls-forms": true,
"tls-forms--large": this.props.type === "S",
"tls-forms--medium tls-forms--login": !(this.props.type === "S")
})}
>
// content here
</div>);
}
Since you need to run animation on each render, you'll need to generate some random key every time (that's why we are calling this.getRandomKey()
on each render). You can use whatever you like for your getRandomKey implementation, though shortid is pretty good for generating unique keys.
One way of animating a component is to attach a CSS class
to it. But, when animation is done, you have to detach the CSS class
so that you can re-attach when you want to animate again.
Here is a basic example:
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
animateFlag: false
};
}
componentDidUpdate() {
if (this.state.animateFlag) {
setTimeout(() => {
this.setState({ animateFlag: false });
}, 3000);
}
}
render() {
return (
<div className="App">
<button
onClick={() =>
this.setState({ animateFlag: !this.state.animateFlag })
}
>
{this.state.animateFlag ? "Wait" : "Re-animate"}
</button>
<div className={this.state.animateFlag ? "text animate" : "text"}>
Hello CodeSandbox
</div>
</div>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
.text {
font-size: 40px;
}
.text.animate {
animation: formFading 3s;
}
@keyframes formFading {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>
Note that, I am setting animateFlag
to false
in ComponentDidUpdate
, so that when I click the Re-animate button
again, I can re-attach the animate
class to the div
element.
I set timeout duration to 3000ms because, the animation takes 3000ms.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With