Ваша функция getRandomItems
может возвращать один и тот же элемент более одного раза, поэтому, когда реакция отображает элементы, их может быть несколько с одинаковым _id
(который используется как key
, поэтому несколько элементов могут иметь тот же key
).
Когда у вас есть несколько <div>
с одним и тем же атрибутом key
, response запутается. Вся суть key
в том, чтобы быть уникальным. Если у вас есть несколько ключей с одним и тем же ключом, при повторном рендеринге react очищает только последний (для любого заданного ключа).
Вот минималистичный пример основной проблемы:
class RandomItems extends React.Component {
constructor(props) {
super(props);
this.state = {
itemsList: [],
loading: true
};
}
componentDidMount() {
const items = [
this.props.data[0],
this.props.data[0],
this.props.data[0]
];
this.setState({
itemsList: items
});
}
onClickTest = () => {
const items = [
this.props.data[1],
this.props.data[2]
];
this.setState({
itemsList: items
});
};
render() {
return (
<div>
{this.state.itemsList.map((item, index) => {
return (
<div key={item.id}>
{item.name}
</div>
)
})}
<button onClick={this.onClickTest}>Test</button>
</div>
)
}
}
/////////////////////////
ReactDOM.render(
<RandomItems randomNums={3} data={[
{id: 0, name: 'Zeroth'},
{id: 1, name: 'First'},
{id: 2, name: 'Second'}
]}></RandomItems>,
document.getElementById('root')
);
<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>
Обратите внимание, когда вы нажимаете «Проверить», что последний из трех «0 Zeroth» div удаляется (как и должно быть), а два других - нет (потому что react не ожидает нескольких div с одним и тем же key
).
Лучшее решение в вашем случае, вероятно, - исправить вашу функцию randomize, чтобы она никогда не возвращала один и тот же элемент несколько раз. Пример:
getRandomItems = () => {
let allItems = [...this.props.data];
const randomCount = this.props.randomNums;
const randomItems = [];
for (let i = 0; i < randomCount; i++) {
const randomIndex = Math.floor(Math.random() * allItems.length);
const randomItem = allItems.splice(randomIndex, 1)[0];
randomItems.push(randomItem);
}
return randomItems;
};
В качестве альтернативы вы можете изменить key
с item._id
на index
, что также устраняет проблему, поскольку index
всегда будет уникальным.