На странице согласования ReactJS есть два примера:
- пример проблем, которые могут быть вызваны использованием индексов в качестве ключей
- обновленная версия того же примера, показывающая, как не использование индексов в качестве ключей исправит эти проблемы с переупорядочением, сортировкой и добавлением
По состоянию на 18 февраля 2020 г. не говоря о том, как воспроизвести проблему на странице. Я попытался нажать «Добавить новый в начало» или «В конец» несколько раз и изменить порядок списка, и они, казалось, работали нормально. Только позже я обнаружил, что вам нужно ввести какой-то текст в поле, а затем просто «Добавить новый в конец», сделать это три раза и изменить порядок списка.
В первом примере текст в поле ввода не было переупорядочено. Во втором примере текст в поле ввода был упорядочен, как и ожидалось.
Две программы отличаются использованием
<ToDo key={index} {...todo} />
против
<ToDo key={todo.id} {...todo} />
Там Также немного переупорядочен код и используется todoCounter
против toDoCounter
(заглавная D
) между двумя версиями, и мне интересно, почему и команда React может исправить это позже. Но вы можете изменить первую версию с key={index}
на key={todo.id}
, и вы также увидите, что проблема решена.
Но потом, когда я посмотрел код, поле ввода фактически не добавляет текстовые данные. в государственную собственность list
(массив). Только id
и createdAt
добавляются для каждой записи в list
.
Итак, хотя мы можем сказать, что использование key={todo.id}
устранило проблему, что вызвало проблему в первую очередь?
Можно сказать, что id
и createdAt
отсортированы правильно. Не правильно отсортированы поля ввода ... но в соответствии с правилом согласования, чтобы решить, следует ли обновить sh фактические элементы DOM на странице, новое поддерево Virtual DOM сравнивается с предыдущим виртуальным поддеревом DOM.
Теперь «свойство» поля ввода value
не является частью виртуального DOM, если только React фактически не помещает value
в виртуальный DOM.
То есть, когда «diff» «Реактивно», React должен думать, что поля ввода одинаковы Так вот как это работает: если мы использовали key={index}
, теперь React различает каждый столбец в текущем виртуальном поддереве DOM с предыдущим и видит, что ячейки «ID» и «createAt» различаются, поэтому refre sh к фактическому DOM. React все равно видел поля ввода и не удосужился вызвать refre sh для фактического DOM.
Однако, если мы используем key={todo.id}
, теперь React будет думать, что весь строка отличается, потому что строка "id" изменилась. Таким образом, React принудительно заставит refre sh к фактическому DOM для всей строки, включая поле ввода.
Таким образом, мы можем сказать, что эта ошибка возникает, только когда некоторые данные не находятся в виртуальном поддереве DOM. редкий, как в данном случае. В других случаях все данные будут выдаваться render()
компонента класса или return
компонента функции, и, следовательно, в состоянии сказать ReactJS, что «да, принудительно вызвать refre sh для фактический DOM ".
Это действительно так работает?