Реактивность массивов в React

Массивы в React также обладают реактивностью. При чем React реактивно реагирует на все изменения массива: на добавление, удаление, изменение элементов, а также на изменение их порядка.

При этом правилами React запрещено изменять сам массив из стейта, он должен быть иммутабельным. Правильным подходом в React является создание нового массива на основе предыдущего и перезапись стейта новым массивом.

Давайте посмотрим, как это осуществляется на практике. Пусть в стейте notes хранится массив:

function App() { const [notes, setNotes] = useState([1, 2, 3, 4, 5]); return <div> </div>; }

Давайте выведем каждый элемент этого массива в отдельном абзаце:

function App() { const [notes, setNotes] = useState([1, 2, 3, 4, 5]); const result = notes.map((note, index) => { return <p key={index}>{note}</p>; }); return <div> {result} </div>; }

Добавление

Давайте добавим в наш массив notes еще один элемент.

Через метод push это делать неправильно, так как мы изменяем сам массив:

notes.push(6); //!! так не правильно setNotes(notes);

Чтобы не изменять сам массив, можно сделать его копию, применить к ней метод push, и затем перезаписать стейт на массив из копии:

const copy = Object.assign([], notes); copy.push(6); // так правильно setNotes(copy);

А можно использовать хитрый прием с деструктуризацией:

setNotes([...notes, 6]); // так правильно

Сделайте кнопку, по нажатию на которую будет происходить добавление нового элемента в массив.

Удаление

Давайте удалим из массива элемент по его номеру. Пусть этот номер хранится в переменной index.

Через метод splice удаление делать неправильно, так как изменятся массив:

notes.splice(index, 1); //!! так не правильно setNotes(notes);

Однако, можно применить splice к копии массива:

const copy = Object.assign([], notes); copy.splice(index, 1); // так правильно setNotes(copy);

Либо использовать деструктуризацию следующим образом:

setNotes([...notes.slice(0, index), ...notes.slice(index + 1)]);

Сделайте кнопку, по нажатию на которую будет происходить удаление элемента из массива. Пусть номер элемента для удаления хранится в переменной.

Изменение

Пусть мы хотим поменять значение некоторому элементу массива. Пусть номер для изменения хранится в переменной index.

Изменять элемент напрямую будет неправильно:

notes[index] = '!'; //!! так не правильно setNotes(notes);

Правильным подходом будет изменить его копию:

let copy = Object.assign([], notes); copy[index] = '!'; // так правильно setNotes(copy);

Либо использовать деструктуризацию:

setNotes([...notes.slice(0, index), '!',...notes.slice(index + 1)]);

Сделайте кнопку, по нажатию на которую будет происходить изменение элемента массива. Пусть номер элемента для изменения хранится в переменной.

Сортировка и переворот

Сортировать массив также будет неправильным, так как функция сортировки изменяет массив:

notes.sort(); //!! так не правильно setNotes(notes);

Правильным подходом будет выполнить сортировку копии:

let copy = Object.assign([], notes); copy.sort(); // так правильно setNotes(copy);

Сделайте кнопку, по нажатию на которую будет происходить переворот элементов массива в обратном порядке.