React имеет несколько алгоритмов для определения того, какие компоненты должны быть перерисованы, в вашем случае React не будет перерисовывать компонент, потому что вы используете индексы, так как ключи и индексы одинаковы. Вам необходимо обновить key
между повторными рендерингами.
В качестве простейшего решения вы можете использовать индекс + некоторый след в ключе, что-то вроде этого:
<Card key={index + '-' + Date.now()} card={card}/>;
В этом случае , компонент <Card/>
будет отображаться каждый раз, когда состояние компонента <Game/>
меняется.
class Card extends React.Component {
constructor(props) {
super(props)
}
render() {
return (
<div class="card">Card {this.props.card.name}</div>
)
}
}
class Game extends React.Component {
constructor(props) {
super(props)
this.state = {
counter: 0,
cards: [
{ name: 'Card1' },
]
}
}
increaseCounter = () => {
this.setState({ counter: this.state.counter + 1 })
}
render() {
return (
<div>
<h2 onClick={this.increaseCounter}>Click me: {this.state.counter}</h2>
<h3>Will be re-rendered</h3>
{this.state.cards.map((card, index) => {
return <Card key={index + '-' + Date.now()} card={card} />;
})}
<h3>Won't be re-rendered</h3>
{this.state.cards.map((card, index) => {
return <Card key={index} card={card} />;
})}
</div>
)
}
}
ReactDOM.render(<Game />, document.querySelector("#app"))
body {
background: #20262E;
padding: 20px;
font-family: Helvetica;
}
#app {
background: #fff;
border-radius: 4px;
padding: 20px;
transition: all 0.2s;
}
h2 {
font-weight: bold;
margin-bottom: 15px;
}
.card{
animation: fade-in-out 3000ms ease-in-out forwards;
}
@keyframes fade-in-out {
0% {
background-color: transparent;
}
50% {
background-color: red;
}
100%{
background-color: transparent;
}
}
<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="app"></div>
НО, для реальных приложений я бы порекомендовал вам рассмотреть возможность использования некоторой библиотеки анимации React, такой как response-transition- группа , потому что, если вы анимируете карты только с CSS, может произойти некоторое мигание, если повторный рендеринг произойдет быстрее, чем время ожидания анимации.