Посібник для початківців для Redux

Розуміння Redux як початківця може заплутати. Redux має безліч нових термінів та понять, які часто бувають досить неінтуїтивними. Цей посібник представляє дуже спрощений приклад реалізації Redux. Я визначатиму кожен із етапів та термінів таким чином, щоб мати сенс для початківця.

Це має бути посібником з демістифікації елементів Redux. Він не містить найбільш технічно точних визначень. У ньому немає найкращих практик. У ньому є визначення, які допоможуть сформувати розуміння для тих, хто не знає цих понять попередньо. Існує проста реалізація, щоб не плутати з непотрібними деталями.

Прикладом, який ми розглянемо у цьому посібнику, буде проста програма todo. Додаток дозволяє користувачеві додавати або видаляти завдання та бачити їх на сторінці.

Я поетапно проаналізую кожен елемент Redux, пояснивши, що це за елемент, і як його реалізувати на прикладах коду. Прокрутіть униз, щоб побачити повний приклад коду, який покаже, як це все поєднується як повна програма React.

Підсумок кроків

  1. Напишіть функцію редуктора
  2. Примірник магазину в кореневому компоненті
  3. Оберніть компоненти компонентом, передаючи в магазин як підпірку
  4. Напишіть компонент
  5. Визначте дії
  6. Визначте відправлення, приєднайте їх до місця, де відправлятимуться відправлення (тобто прослуховувачі подій тощо)
  7. Визначте функцію mapStateToProps
  8. Експортуйте функцію підключення, передавши в mapStateToProps і null як 2 аргументи та передавши ім'я компонента у другу пару дужок

Кроки

1. Напишіть функцію редуктора

Функція редуктора - це функція, яка повідомляє магазину, як реагувати на дії. Функція повертає новий та оновлений стан щоразу, коли відправляється дія. Стан незмінний (його не можна змінити), тому редуктор завжди повертає новий стан. Редуктор зазвичай використовує оператор поширення для вставки поточного стану в новий об'єкт / масив та додавання до нього. Поширеною практикою є використання оператора switch / case та перевірка властивості type переданої дії. Потім напишіть код, який оновлює стан для кожного випадку.

Спочатку ми пишемо свою функцію редуктора, тому що нам потрібно буде передати її, коли створюємо екземпляр нашого магазину. Щоб зрозуміти, що відбувається, потрібно певне знання дій та відправлення. Ми розглянемо це далі в цьому посібнику.

Наразі знайте, що нашій програмі завдання потрібно буде взаємодіяти з магазином двома способами: додати новий пункт завдання до стану та видалити елемент завдання із стану. Тому ми пишемо свою функцію так, щоб вона реагувала на 2 випадки типу дії. Він використовує значення дії для додавання або видалення завдання із стану.

Редуктору передається 2 параметри: стан (це весь стан, який зараз знаходиться в сховищі, і ми надаємо йому значення за замовчуванням, якщо стан ще не існує) та дію. Ми повертаємо стан у випадку за замовчуванням.

2. Примірник магазину в кореневому компоненті

Магазин - це те, що насправді містить стан у ньому. Це трохи чарівно, і вам насправді не потрібно знати тонкощі та недоліки цього. Все, що вам потрібно знати, це те, що ви не отримуєте до нього безпосереднього доступу, як у звичайному стані React. Ви отримуєте доступ до нього та вносите до нього зміни, використовуючи редуктори, дії та відправлення.

Інше важливе, що слід знати про магазин, - це те, що він містить кілька корисних і важливих методів. Основним методом є функція диспетчеризації. Він також містить метод getState (для перегляду стану) і метод subscribe (запускає зворотний виклик кожного разу, коли відправляється дія).

Зберігання зазвичай створюється у кореневій частині вашої програми (наприклад, App.js). Він зберігається як змінна, а редуктор передається як параметр. Потім сховище передається як властивість компоненту Провайдер.

Ми створюємо екземпляр нашого об’єкта магазину, передаючи щойно створений редуктор.

3. Оберніть компоненти компонентом, передаючи в магазин як підпірку

Постачальник - це компонент, створений для полегшення передачі сховища всім вашим компонентам. Компонент Постачальника обгортає всі Ваші компоненти (наприклад, надає Ваші компоненти як дочірні Постачальника). Ви передаєте магазин як підставку лише Постачальнику. Це означає, що вам не потрібно передавати в магазин як підставку до кожного компонента, оскільки кожен компонент отримує його від постачальника. Однак це не означає, що компоненти ще мають доступ до держави. Вам все одно потрібно використовувати mapStateToProps (ми розглянемо це пізніше), щоб мати доступ до стану у вашому компоненті.

Ми обгортаємо компонент Todo, який ми збираємось зробити, із нашим компонентом Provider. Ми проходимо в магазин, який ми створили на попередньому кроці.

4. Напишіть компонент

Далі ми починаємо писати компонент Todo, який буде відображати елементи завдання та взаємодіяти з магазином Redux.

Компонент - це компонент із станом, що містить один елемент стану, щоб відстежувати те, що користувач набрав у введенні. У нас є функція, яка називається handleChange. Ця функція оновлює стан кожного разу, коли користувач щось вводить у вхід. Поки що це все, що ми напишемо. Нам слід більше зрозуміти Redux, перш ніж ми зможемо написати логіку. Логіка додасть нові задачі до стану і отримає поточні із стану для відображення на сторінці.

5. Визначте дії

Дія - це простий об'єкт, що містить властивість, що називається 'тип'. Цей об'єкт передається у функцію відправлення. Він використовується, щоб повідомляти магазину, яка подія щойно сталася (читаючи властивість type actions). Він також повідомляє, яке оновлення він повинен внести до стану у відповідь (за допомогою функції редуктора). Дія може також містити інші властивості для будь-яких інших даних, які ви хочете передати в редуктор. Дані можна передавати лише звідси, тому будь-які потрібні дані потрібно буде передати сюди.

Для визначення наших дій ми використовуватимемо творців дій. Творці дій - це функція, яка повертає об’єкт дії. Його мета - зробити дію більш портативною та перевіряється. Це не змінює поведінку того, як щось працює. Це ще один спосіб написання та передачі дії. Це також дозволяє передавати параметри, якщо ви хочете надіслати дані з дією, яку ми будемо робити. Тому ми вимагаємо використовувати тут творців дій.

Якщо ви пам’ятаєте, наш редуктор відповів на 2 типи дій - “ADD_TODO” та “REMOVE_TODO”. Ми визначимо ці дії з нашими творцями дій. У нашій дії add_todo повернеться "ADD_TODO" як тип, і елемент завдання, який ми хочемо додати до сховища як значення (нам потрібно, щоб магазин додав цей елемент завдання до стану, щоб він був тут переданий). У remove_todo ми повертаємо “REMOVE_TODO” як тип, а індекс елемента завдання в магазині як значення. Це нам знадобиться, щоб вилучити його зі списку завдань.

Якщо ви повернетесь до нашого визначення функції редуктора, сподіваємось, тепер це має більше сенсу. Читаючи action.type, редуктор знає, чи потрібно додавати завдання до стану або видаляти його з нього. Він має елемент todo, переданий в add_todo. Він додається до поточного стану за допомогою оператора поширення. У remove_todo він використовує оператор поширення, щоб створити новий масив, що додає поточний стан, нарізаний двічі, один раз з усіма елементами перед тим, який потрібно видалити, і другий з усіма елементами після того, який потрібно видалити, таким чином створюючи наш новий об'єкт стану за допомогою елемент todo видалено.

Однак це все ще не є повною картиною. Ми ще не розглянули, як редуктор викликається та передається в правильній дії. Для цього нам потрібно буде перейти до визначення нашої функції відправки.

6. Визначте диспетчерику, приєднайте їх до того місця, де будуть ініційовані депеші (тобто прослуховувачі подій тощо)

Функція відправки - це метод зберігання, який використовується для ініціювання зміни стану. Будь-яка подія або щось, що потребує оновлення стану, повинно викликати метод відправлення для цього. Це єдиний спосіб викликати зміну / оновлення стану. Викликається відправка та передається об’єкт дії (або творець дії, якщо він був використаний). Як тільки диспетчеризація спрацьовує, магазин потім викликає функцію редуктора і передає дію, яку надала диспетчера, яка оновлює стан, як ми бачили раніше.

Нижче ми визначаємо нижню половину нашого методу візуалізації компонентів. Ми створюємо наші кнопки, які містять наші обробники подій. Всередині них ми визначимо наші функції відправлення.

Перша кнопка - це проста кнопка додавання. Ця кнопка надішле дію add_todo до магазину. Він передаватиметься в поточному введенні користувачем як значення (це елемент завдання, який редуктор додає до нового стану). Зверніть увагу, що ми називаємо відправлення як this.props.dispatch. Це трохи виходить за рамки цього посібника, щоб зрозуміти, як і чому це передається як допомога компоненту. Тож просто знайте, що це так, і ми можемо називати це так.

Другий обробник події записується як onClick на нашому відтвореному елементі завдання. Натискаючи будь-який елемент завдання на сторінці, він запускає обробник подій. Обробник подій здійснює пошук у списку завдань та знаходить індекс цього завдання в списку. Потім він відправляє дію remove_todo і передає в індекс.

На сьогодні повністю визначений цикл оновлення стану в магазині Redux. Ми знаємо, що в будь-який час, коли ми хочемо змінити стан, нам потрібно викликати метод диспетчеризації, передати відповідну дію та переконатися, що наш редуктор обробляє ці дії та повертає новий стан, використовуючи будь-які значення, які ми передали через дію.

Єдина частина головоломки, якої зараз не вистачає, - це те, як ми можемо отримати стан від магазину Redux. Ви, напевно, помічали, що я склав список, названий this.props.todosу попередньому прикладі. Можливо, вам цікаво, звідки це взялося. Ви також можете згадати на початку цього посібника, про який я згадав, що переходу магазину до компонента Провайдер недостатньо для отримання доступу до стану в магазині. Це все розглядається на наступних 2 кроках, коли ми визначаємо нашу функцію mapStateToProps і передаємо її у функцію connect.

7. Визначте функцію mapStateToProps

Коли ви хочете, щоб ваш компонент мав доступ до стану, вам слід чітко вказати, до якого стану він отримає доступ. Без цього ваш компонент не матиме доступу до стану.

mapStateToProps - це функція, яка просто повертає об'єкт, який визначає, який стан повинен бути переданий компоненту, присвоюючи значення в стані властивостям, визначеним у цьому об'єкті. По суті, об’єктом, який ви повертаєте у mapStateToProps, є те, що ваш реквізит буде у вашому компоненті. Функція mapStateToProps передається в метод connect як перший аргумент.

MapStateToProps приймає в якості параметра весь стан, і ви берете з нього лише те, що вам потрібно. Ось тут, оскільки наша держава містить лише список тодо. Нам потрібен цей список у нашому компоненті ToDo, ми повернемо весь стан як властивість під назвою todos.

Як ви можете бачити зараз, ми маємо доступ до всього нашого списку завдань у нашому реквізиті як this.props.todos. Ось як ми змогли зробити всі наші завдання в попередньому прикладі, наклавши на нього карту.

Нарешті нам потрібно передати цю функцію в наш метод connect, щоб з’єднати все разом.

8. Експортуйте функцію підключення, передавши в mapStateToProps і null як 2 аргументи та передавши ім'я компонента у другу пару дужок

Connect - це метод, який підключає функції mapStateToProps та mapDispatchToProps (див. Нижче) до вашого компонента, щоб магазин міг читати ці функції та забезпечувати передачу того, що ви там визначили, у компонент як пропс. Цей метод має спеціальний синтаксис, який виглядає так:

connect(mapStateToProps, MapDispatchToProps)(YourComponent)

Ви передаєте 2 map...ToPropsфункції до з'єднання, а потім ім'я вашого компонента всередині другої пари дужок. Типовим шаблоном є експорт методу підключення замість компонента, коли ви експортуєте компонент у кінці файлу. Наприклад:

export default connect(mapStateToProps, MapDispatchToProps)(YourComponent)

Потім це діє так само, як нормальний експорт, за винятком стану, і відправки передаються як реквізит. mapStateToProps і mapDispatchToProps насправді є необов’язковими параметрами для підключення. Якщо ви не хочете передати один або один із них, поставте замість них null.

Можливо, вам цікаво, звідки взялася ця функція mapDispatchToProps, і чому ми раніше ніде про неї не згадували. Ну, оскільки цей посібник є найбільш спрощеним прикладом магазину Redux, і mapDispatchToProps не є суворо обов’язковим, я не включив його в наш приклад. Якщо ви не передаєте mapDispatchToProps і натомість передаєте значення null, ви все одно можете отримати доступ до функції відправки у вашому компоненті, як це було раніше this.props.dispatch.

Отже, щоб закінчити наш приклад програми, все, що нам потрібно зробити, - це експортувати наш компонент, обертаючи його функцією connect та передаючи в mapStateToProps, який ми щойно визначили.

І це все! Це повна реалізація магазину Redux. Дивіться нижче робочий приклад того, що ми впровадили.

Повний приклад кодованого коду

App.js Todo.js

Я сподіваюся, що цей посібник може спростити деякі дивні, а часом і заплутані деталі Redux. Це не повний путівник Redux, оскільки, безумовно, є більше елементів та шаблонів, які слід зрозуміти. Але якщо ви можете зрозуміти цей посібник, ви вже на шляху до того, щоб мати можливість працювати з Redux та встановлювати його у своїх програмах.