Reputation: 679
I want to play an animation on a react component every time it rerenders due to prop change:
react:
function Card({ cardText }) {
return <div className="roll-out">{cardText}<div/>
}
So I did css:
@keyframes rollout {
0% { transform: translateY(-100px); }
100% { transform: none; }
}
.roll-out {
animation: rollout 0.4s;
}
However, the animation only plays once, on the initial render. I want to play it every time <Card />
re-renders due to cardText
change. How can I achieve it?
Upvotes: 39
Views: 37401
Reputation: 5079
Add a key
like this:
function Card({ cardText }) {
return <div key={cardText} className="roll-out">{cardText}<div/>
}
In your code, when the div re-renders, react only changes its inner text. Adding a key will make react think it's a different div when the key changes, so it'll unmount it and mount again.
Upvotes: 75
Reputation: 4135
To force element to re-render you can simply change its key
prop which will trigger a render making react think its another element
Refer this answer: https://stackoverflow.com/a/35004739
function Card({
cardText
}) {
return <div className = "roll-out" > {
cardText
} </div>
}
ReactDOM.render( (<Card cardText="Hey There" />) , document.getElementById('root'))
@keyframes rollout {
0% {
transform: translateY(-100px);
}
100% {
transform: translateY(0);
}
}
.roll-out {
animation: .4s rollout;
}
<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>
Upvotes: 3
Reputation: 365
The trick here is to use a random key
field on your card element. React's diffing algorithm considers elements with the same key as the same, so randomizing the key will make react consider each rerendered element as new, so will removed the old element from the DOM and add a brand new one
Here is a demo using @aXuser264 's code as a base.
class Card extends React.Component{
onClick = ()=>this.forceUpdate();
render(){
return <div key={Math.random()} className="roll-out" onClick={this.onClick}> {
this.props.cardText
} </div>
}
}
ReactDOM.render( (<Card cardText="Hey There" />) , document.getElementById('root'))
@keyframes rollout {
0% {
transform: translateY(-100px);
}
100% {
transform: translateY(0);
}
}
.roll-out {
animation: .4s rollout;
}
<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>
Upvotes: 14