Ця відповідь полягає у наданні достатньої кількості інформації, щоб не змінювати / не змінювати стан безпосередньо в React.
React слідує за односпрямованим потоком даних . Це означає, що потік даних всередині реакції повинен і, як очікується, матиме круговий шлях.
Потік даних React's без потоку
Щоб React працював так, розробники зробили React подібним до функціонального програмування . Основним правилом функціонального програмування є незмінність . Дозвольте пояснити це голосно та чітко.
Як працює односпрямований потік?
states
- це сховище даних, яке містить дані компонента.
view
Компонента надає на основі стану.
- Коли
view
потрібно щось змінити на екрані, це значення слід подавати з store
.
- Щоб це сталося, React надає
setState()
функцію, яка приймає object
new states
і виконує порівняння та злиття (подібне до object.assign()
) попереднього стану та додає новий стан до сховища даних стану.
- Кожного разу, коли дані у сховищі стану змінюються, реакція викликає повторний візуалізацію з новим станом, який
view
споживає, і відображає його на екрані.
Цей цикл триватиме протягом усього життя компонента.
Якщо ви бачите наведені вище кроки, це ясно показує, що багато чого відбувається позаду, коли ви змінюєте стан. Отже, коли ви безпосередньо мутуєте стан і викликаєте setState()
порожній об'єкт. Вода previous state
буде забруднена вашою мутацією. Через що неглибоке порівняння та злиття двох станів буде порушено або не відбудеться, оскільки зараз у вас буде лише один стан. Це порушить усі методи життєвого циклу React.
Як результат, ваш додаток буде вести себе ненормально або навіть аварійно працювати. У більшості випадків це не вплине на ваш додаток, оскільки всі додатки, які ми використовуємо для тестування, досить малі.
І ще одним недоліком мутації Objects
та Arrays
в JavaScript є те, що коли ви призначаєте об'єкт або масив, ви просто робите посилання на цей об'єкт або цей масив. Коли ви його мутуєте, це вплине на все посилання на цей об’єкт або на цей масив. React обробляє це розумно у фоновому режимі і просто надає нам API, щоб він працював.
Найпоширеніші помилки, допущені під час обробки станів у React
this.state = {
a: [1,2,3,4,5]
}
const b = this.state.a.push(6)
this.setState({
a: b
})
У наведеному вище прикладі this.state.a.push(6)
буде мутувати стан безпосередньо. Присвоєння його іншій змінній та виклик setState
- те саме, що показано нижче. Оскільки ми все одно мутували стан, немає сенсу призначати його іншій змінній і викликати за setState
допомогою цієї змінної.
this.state.a.push(6)
this.setState({})
Більшість людей робить це. Це так неправильно . Це порушує красу React, і це зробить вас поганим програмістом.
Отже, який найкращий спосіб обробляти стани в React? Дозволь пояснити.
Коли вам потрібно змінити "щось" у існуючому стані, спочатку отримайте копію цього "чогось" із поточного стану.
this.state = {
a: [1,2,3,4,5]
}
const currentStateCopy = [...this.state.a]
Тепер мутація currentStateCopy
не змінить початковий стан. Виконайте операції currentStateCopy
та встановіть його як новий стан за допомогою setState()
.
currentStateCopy.push(6)
this.state({
a: currentStateCopy
})
Це красиво, правда?
Роблячи це, всі посилання на this.state.a
не впливатимуть, поки ми не використаємо setState
. Це дає вам можливість контролювати свій код, і це допоможе вам написати елегантний тест і зробити вас впевненими у роботі коду у виробництві.
Щоб відповісти на ваше запитання,
Чому я не можу безпосередньо змінити стан компонента?
Так, ти можеш . Але вам доведеться зіткнутися з наступними наслідками.
- Під час масштабування ви будете писати некерований код.
- Ви втратите контроль над
state
усіма компонентами.
- Замість того, щоб використовувати React, ви будете писати власні коди над React.
Незмінність не є необхідною річчю, оскільки JavaScript є однопоточним. Але, добре дотримуватися практики, яка допоможе вам у довгостроковій перспективі.
PS. Я написав близько 10000 рядків змінного коду React JS. Якщо це зламається зараз, я не знаю, де шукати, тому що всі значення десь мутують. Коли я це зрозумів, я почав писати незмінний код. Довірся мені! Це найкраще, що ви можете зробити з продуктом або додатком.
Сподіваюся, це допомагає!
setState
документації . Він охоплює деякі вагомі причини.