Стан компонента
Для чого потрібен метод setState
?
Метод setState()
призначає зміни об’єкта стану (state)
. У відповідь на зміни стану компонент рендериться повторно.
У чому полягає різниця між state
та props
?
props
(скороч. від англ. “properties” — властивості) і state
— це звичайні JavaScript-об’єкти. Хоча обидва містять інформацію, що впливає на результат рендерингу, існує одна істотна відмінність: props
передаються в компонент (подібно до параметрів функції), у той час як state
знаходиться у компоненті (подібно до оголошення змінних усередині функції).
Для подальшого ознайомлення з поняттями пропсів
та стану
рекомендуємо наступні статті:
Чому setState
видає невірне значення?
У React, як this.props
, так і this.state
представляють уже відрендерені значення, тобто те що наразі знаходиться на екрані.
Виклик setState
— асинхронний, тому не варто розраховувати, що this.state
відобразить нове значення відразу ж після виклику. Якщо вам потрібно розрахувати значення, засновані на поточному стані, замість об’єкта передайте функцію оновлення (детальну інформацію див. нижче).
Приклад коду, що не працюватиме належним чином:
incrementCount() {
// Примітка: код *не* працюватиме належним чином.
this.setState({count: this.state.count + 1});
}
handleSomething() {
// Припустимо, що `this.state.count` починається з 0.
this.incrementCount();
this.incrementCount();
this.incrementCount();
// Коли React повторно відрендерить компонент, `this.state.count` буде дорівнювати 1 замість очікуваних 3.
// Це відбувається тому, що попередня функція — `incrementCount()` бере своє значення зі `this.state.count`,
// але React не оновить `this.state.count` доки компонент не відрендериться повторно.
// Тож, кожного разу `incrementCount()` зчитує значення this.state.count як 0 і встановлює його рівним 1.
// Нижче розглянемо як вирішити дану проблему!
}
Див. нижче як вирішити цю проблему!
Як оновити значення, що залежить від поточного стану?
Замість об’єкта передайте до setState
функцію, щоб впевнитись, що виклик завжди використовує актуальну версію стану (див. нижче).
У чому полягає різниця між передачею об’єкта або функції у setState
?
Передача функції оновлення надає доступ до поточного стану всередині самої функції. Оскільки виклики setState
згруповані, це дозволяє послідовно виконати оновлення і гарантує те, що зміни будуть виконуватися по черзі, а не конфліктувати одна з одною:
incrementCount() {
this.setState((state) => {
// Важливо: використовуйте `state` замість `this.state` при оновленні.
return {count: state.count + 1}
});
}
handleSomething() {
// Припустимо, що `this.state.count` починається з 0.
this.incrementCount();
this.incrementCount();
this.incrementCount();
// Значення `this.state.count` все ще дорівнює 0.
// Але коли React повторно відрендерить компонент, значення дорівнюватиме 3.
}
Коли setState
працює асинхронно?
Наразі, setState
працює асинхронно усередині обробників подій.
Це гарантує, наприклад, що якщо Батьківський
та Дочірній
компоненти викликають setState
під час натискання, то Дочірній
компонент не буде відрендерений двічі. Замість цього, React “відкладає” оновлення стану до моменту закінчення роботи події. Це допомагає значно підвищити продуктивність великих додатків.
Це деталь реалізації, а тому не покладайтесь на неї безпосередньо. У майбутніх версіях React буде за замовчуванням групувати оновлення стану.
Чому React не оновлює this.state
синхронно?
Як згадувалось раніше, перед початком повторного рендерингу React навмисно “очікує” доки всі компоненти викличуть setState()
у своїх обробниках подій. Це дозволяє прискорити продуктивність уникаючи повторного рендерингу.
У вас може виникнути питання, чому React просто відразу не оновить this.state
.
Існує дві причини:
- Це порушить узгодженість між
props
таstate
, спричиняючи велику кількість помилок. - Це зробить реалізацію нових функцій неможливою.
У цьому GitHub-коментарі дана тема розглядається глибше.
Чи варто використовувати бібліотеки управління станом, такі як Redux чи MobX?
Перед застосуванням додаткових бібліотек варто досконало вивчити React. Використовуючи тільки його можна створити досить складні додатки.