A key
- единственное, что React использует для идентификации DOM
элементов.
Чтобы понять работу key
, давайте сначала разберемся с поведением React без key
.
Допустим, у нас есть список
<ul>
<li>first</li>
<li>second</li>
</ul>
По умолчанию при рекурсии по дочерним элементам узла DOM
React просто выполняет итерацию по обоим спискам дочерних элементов одновременно и генерирует мутацию всякий раз, когда есть разница.
Например, при добавлении элемента в конце дочерних элементов преобразование между этими двумя деревьями работает хорошо:
<ul>
<li>first</li>
<li>second</li>
<li>third</li>
</ul>
React
будет соответствовать два дерева <li>first</li>
, сопоставьте два дерева <li>second</li>
, а затем вставьте дерево <li>third</li>
.
Вставка элемента в beginning
имеет худшую производительность. Например, преобразование между этими двумя деревьями работает плохо, и React мутирует каждого дочернего элемента вместо того, чтобы понимать, что он может сохранить поддеревья <li>Duke</li>
и <li>Villanova</li>
нетронутыми. Эта неэффективность может быть проблемой.
Ключи
Чтобы решить эту проблему, React поддерживает атрибут key
. Когда дочерние элементы имеют keys
, React использует key
для сопоставления дочерних элементов в исходном дереве с дочерними элементами в последующем дереве.
Например, добавление key
к нашему неэффективному примеру выше может сделать дерево эффективность преобразования:
<ul>
<li key="2015">Duke</li>
<li key="2016">Villanova</li>
</ul>
<ul>
<li key="2014">Connecticut</li>
<li key="2015">Duke</li>
<li key="2016">Villanova</li>
</ul>
Теперь React знает, что элемент с ключом '2014'
является новым, а элементы с ключами '2015'
и '2016'
только что перемещены.
Теперь давайте поговорим о вашей проблеме
Свойство key
в React дает вам возможность управлять экземплярами компонентов. Каждый раз, когда React визуализирует ваши компоненты, он вызывает ваши функции для получения новых элементов React, которые он использует для обновления файла DOM
. Если вы возвращаете те же типы элементов, он сохраняет эти components/DOM
узлы, даже если все * свойства изменились.
В вашем случае экземпляры компонентов обновляются и повторно используются на основе их ключа. При изменении key
списка состояние компонента для таких вещей, как неконтролируемые вводы, может быть перепутано и обновлено неожиданными способами.