Ваша первая версия нарушила одно из основных правил React, изменив состояние напрямую (подробнее об этом в этой части документов ). Строка
let newListCollapsed = listCollapsed;
просто заставляет newListCollapsed
и listCollapsed
оба ссылаться на один и тот же массив (тот, который используется в качестве состояния), не копирует массив. Когда вы сделаете это, вы получите следующее:
state:Ref5461−−−−−−−−−−−−−−−−+
\ +−−−−−−−−−−−+
listCollapsed:Ref5461−−−−−−−−−−+−−−−>| (array) |
/ +−−−−−−−−−−−+
newListCollapsed:Ref5461−−−−−+ | 0: false |
| 1: false |
| ... |
+−−−−−−−−−−−+
Так что
setListCollapse(newListCollapsed);
ничего не делает, потому что он устанавливает тот же массив, который уже содержится в состоянии. React не видит никаких изменений.
Но эта строка:
let newListCollapsed = [...listCollapsed];
копирует массив в новый массив (с использованием нотации распространения, чтобы разложить его записи в новый массив, созданный литералом []
), поэтому у вас есть:
state:Ref5461−−−−−−−−−−−−−−−−+
\ +−−−−−−−−−−−+
listCollapsed:Ref5461−−−−−−−−−−+−−−−>| (array) |
+−−−−−−−−−−−+
| 0: false |
| 1: false |
| ... |
+−−−−−−−−−−−+
+−−−−−−−−−−−+
newListCollapsed:Ref8465−−−−−−−−−−−−>| (array) |
+−−−−−−−−−−−+
| 0: false |
| 1: false |
| ... |
+−−−−−−−−−−−+
Так что, когда вы вызываете setListCollapse(newListCollapsed);
, это не то же самое, и изменение делается. Это правильная вещь.
(Значения Ref####
на этих диаграммах являются концептуальными. Это ссылки на объекты для двух массивов. Ссылка на объект сообщает механизму JavaScript, где объект находится в памяти. Вы никогда не увидите фактическое значение ссылки на объект в своем коде.)