Предупреждение: flattenChildren (...): обнаружены два ребенка с одним и тем же ключом/дочерние ключи должны быть уникальными
Вчера я добавил react-router-dom
в свой проект, и теперь, когда я ухожу и возвращаюсь к элементу Sky
в моем навигаторе, он перезагружает небо, и я получаю
Предупреждение: flattenChildren (...): Обнаружены два ребенка с одним и тем же ключом, element-id-50
. Детские ключи должны быть уникальными; когда у двух детей есть ключ, будет использоваться только первый ребенок.
(номер 50, использованный выше, является просто примером, он выдает эту ошибку ~ 40 раз каждый раз с разными идентификаторами)
Проблема, похоже, проистекает из моего файла sky.js
:
componentWillMount() {
this.props.dispatch(requestSkySetup());
this.props.dispatch(requestAllElements());
this.setState({loadedSky: true, loadedElements: true});
}
Поскольку каждый раз, когда я иду на другой экран, этот компонент размонтируется, а затем снова монтируется, когда я возвращаюсь.
Когда receiveSkySetup
завершено, функция render
в sky.js
создает кучу divs под названием Sector
, и каждый Sector
создает несколько divs под названием Slot
s.
Тогда внутри Slot.render
у меня есть:
return connectDropTarget(
<div className={showOutline ? 'slot showOutline' : 'slot'} style={style} onClick={interactable ? this.handleClick : null}>
{
elements
.map(e => (
<SkyElement
id={e.id}
key={`element-id-${e.id}`}
title={e.title}
size={150}
opacity={e.opacity}
glow={e.glow}
color={e.color}
sectorId={e.sectorId}
slotId={e.id}
dispatch={this.props.dispatch}
isDragging={false}
transformElement={false} />
))
}
</div>
);
Элемент key
в вызове SkyElement
выше - это то, что бросает 40+ ошибок на каждом монтаже.
С удовольствием предоставим больше кода при необходимости.
Любая помощь будет чрезвычайно полезна. Спасибо!
Изменить: элементы ведения журнала консоли
Копаясь немного больше, предметы удваиваются в моем магазине.
Итак, на втором рендере вкладки Sky
полный список идентификаторов элементов ["0", "1", "2", "3", "4", "5", "6", "7", "17", "18", "19", "55", "56", "57", "58", "59", "60", "61", "62", "63", "64", "65", "66", "67", "77", "78", "0", "1", "2", "3", "4", "5", "6", "7", "17", "18", "19", "55", "56", "57", "58", "59", "60", "61", "62", "63", "64", "65", "66", "67", "77", "78"]
На третьем рендере элементы 0-78 (иды, которые применяются из массива выше) будут добавлены снова в массив
В Slot.js
const mapStateToProps = ({elements}, ownProps) => {
return {
elements: getElementsBySlotId(elements, ownProps.id),
};
};
elements
здесь будет n
умножить на количество нагрузок, сделанных Sky
.
В sky.js
const mapStateToProps = ({sky, elements}) => {
return {
sectors: getSky(sky).sectors,
elements: getElementsByKeyName(elements, 'visibleElements'),
unplacedElements: getElementsByKeyName(elements, 'unplacedElements'),
};
};
Печать elements.length
Я вижу, что они тоже здесь удваиваются. Slot.js вытаскивает из одного и того же хранилища, поэтому имеет смысл
В моем elements/reducer.js
case 'receiveAllElements':
const visibleElements = {};
const unplacedElements = {};
const elements = action.elements.reduce((result, index) => {
result[`${index.id}`] = index;
return result;
}, {});
const keys = Object.keys(elements);
for (const key of keys) {
const e = elements[key];
if (e.sectorId === null) {
unplacedElements[key] = e;
} else {
visibleElements[key] = e;
}
}
const visibleIds = Object.keys(visibleElements);
const unplacedIds = Object.keys(unplacedElements);
console.log(visibleIds);
console.log(unplacedIds); // logging these, the numbers are consistent and don't double, triple etc with each load
return {
...state,
elementsMap: {
...state.elementsMap,
...elements,
},
visibleElements: [...state.visibleElements, ...visibleIds],
unplacedElements: [...state.unplacedElements, ...unplacedIds],
};
Может быть, что-то там вызывает удвоение счета?
Ответы
Ответ 1
Проблема здесь была
return {
...state,
elementsMap: {
...state.elementsMap,
...elements,
},
visibleElements: [...state.visibleElements, ...visibleIds],
unplacedElements: [...state.unplacedElements, ...unplacedIds],
};
а именно значения visibleElements
(и unplacedElements
).
[...state.visibleElements, ...visibleIds]
будет concat 2 массивов, так как этот код попадал каждый раз, когда я возвращался на вкладку Sky
, он добавлял новые идентификаторы в ...visibleIds
к массиву, который у меня уже был в ...state.visibleElements
и значения удвоения