Руководство по настройке Redux Toolkit в React

Кто-нибудь испытывает сложности, когда вы хотите реализовать Redux в своем приложении react? Очень часто кажется, что внедрение Redux в самом начале требует слишком больших усилий, особенно потому, что в Redux много шаблонов, и не всегда запоминаются все шаги.

К счастью, теперь у нас есть Redux Toolkit, который может ответить на наше нежелание. Несмотря на то, что Redux Toolkit облегчает нам жизнь, мы до сих пор не можем вспомнить все шаги. Поэтому мы решили сделать простой урок для ваших заметок.

Важные моменты в Redux

Не будем заострять внимание на самой концепции Redux, но упомянем важные моменты, касающиеся Redux.

  • Redux — глобальное состояние
  • Redux не нужен для каждого проекта.
  • Вам может понадобиться Redux, если вы не хотите передавать props (пропускать props слишком глубоко).
  • Если вы все еще не уверены в Redux, просто подумайте о состоянии React. Единственная разница в том, что вы можете получить доступ к состоянию из любого места.
Redux — глобальное состояние

По сути, это состояние React. Что вы можете сделать, если у вас есть состояние React? Вы можете получить состояние и установить состояние, верно?

// Initial state
const [count, setCount] = useState(0);

// get state
console.log(count);

// set state
setCount(1);

Просто помните эту концепцию get и set . В Redux мы можем думать, что get это selector, и set этоdispatch

Если вы хотите изучить более подробно, предлагаю прочитать эту документацию .

Особенно эта иллюстрация.

Redux-иллюстрация

Выполнение

давайте перейдем к хорошей части!

Установка

Вам нужно всего два пакета npm.

npm install @reduxjs/toolkit react-redux

Создать store Redux

src/app/store.js

import { configureStore } from '@reduxjs/toolkit';

export default configureStore({
  reducer: {},
});

Настроить магазин

Я хочу немного рассказать о настройке хранилища. ConfigureStore принимает только один параметр — Object , который называется ConfigureStoreOptions. Обратите внимание еще раз на наш фрагмент

ConfigureStoreOptions имеет несколько атрибутов ( ? означает необязательный ):

  • reducers
  • middleware​?
  • devTools​?
  • preloadedState​?
  • enhancers​?

Наиболее важными и простыми для понимания являются reducers, devTools, иpreloadedState

Reducers (объект)

Атрибут редукторов является обязательным параметром, который мы помещаем в качестве атрибутов. Имя атрибута будет связано с селектором. Я объясню позже.

DevTools​ (логическое значение)

Redux-devtools

Это важно для вашей среды разработки. Значение по умолчанию — true, поэтому добавлять этот атрибут не обязательно. Однако этот атрибут может понадобиться для производственной среды.

PreloadedState (объект)

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

Включите Redux Store в родительский элемент App.js

Благодаря этому все ваше приложение сможет получить доступ к Redux.

Оберните свой <App /> компонент с помощью Provider и включите хранилище, которое вы недавно создали.

//...
import { Provider } from 'react-redux';
import store from './app/store';


// ...
  <Provider store={store}>
    <App />
  </Provider>
// ...

Создайте фрагмент состояния Redux

Основная идея здесь заключается в том, что Slice создаст действие, которое мы будем использовать для отправки, и reducer, который мы будем использовать в configureStore.

src/features/todo/todoSlice.js

import { createSlice } from '@reduxjs/toolkit';

export const todoSlice = createSlice({
  name: 'todos',
  initialState: [],
  reducers: {
    addTodo: (state, action) => {
      const todo = {
        id: uuid(),
        text: action.payload,
      };

      state.push(todo);
  },
});

// this is for dispatch
export const { addTodo } = todoSlice.actions;

// this is for configureStore
export default todoSlice.reducer;

Вот самая сложная часть реализации redux. Мы предполагаем, что вы уже знаете о reducer Redux. Благодаря createSlice нам не нужно вручную реализовывать reducer Redux. Однако есть кое-что, что вам нужно иметь в виду. CreateSlice из Redux Toolkit встроен в Immer.

Когда мы хотим обновить состояние React, мы не можем его изменить. Поэтому нам нужно создать совершенно новые данные для обновления состояния. Это та же парадигма в обычном Redux.

Однако Иммер облегчает нам жизнь. Мы можем напрямую изменять состояние. Взгляните на наш пример в addTodo функции reducer. Мы ничего не возвращаем, а просто изменяем состояние.

addTodo: (state, action) => {
  const todo = {
    id: uuid(),
    text: action.payload,
  };

  // mutate the state
  state.push(todo);
}
Изменение состояния — не единственный способ обновить состояние. Мы также можем использовать концепцию неизменяемости Redux, которая использует return
addTodo: (state, action) => {
  const todo = {
    id: uuid(),
    text: action.payload,
  };

  // return a new data
  return [...state, todo];
}

Полную документацию Redux Toolkit по Immer вы можете прочитать здесь .

Добавьте срезы Reducers в Store

import { configureStore } from '@reduxjs/toolkit';
import todoReducer from '../features/todo/todoSlice';

export default configureStore({
  reducer: {
    todos: todoReducer,
  },
});

Реализация useSelector и useDispatch в компонентах React

useSelector

Ранее мы упоминали, что если вы хотите получить состояние, вы будете использовать селектор. Вот как вы можете получить доступ к состоянию редукции.

import React from 'react';
import { useSelector } from 'react-redux';

export default function Todos() {
  const todos = useSelector((state) => state.todos);
  // todos comes from the reducer attribute name 
  // in configureStore

  return (
    <div>
      <ul>
        {todos.map((todo) => (
          <li key={todo.id}>
            <span>{todo.text}</span>
          </li>
        ))}
      </ul>
    </div>
  );
}

export default configureStore({
  reducer: {
    todos: todosReducer,
    // state.todos comes from this attribute name
  },
});

useDispatch

Наконец, если мы хотим изменить глобальное состояние, нам нужно использовать Dispatch и действие, которое мы уже создали в срезе.

import React, { useState } from 'react';
import { useDispatch } from 'react-redux';
import { addTodo } from '../features/todos/todosSlice';

export default function AddTodo() {
  const [text, setText] = useState('');
  // initial the dispatch here
  const dispatch = useDispatch();

  const addTodoHandler = (event) => {
    event.preventDefault();
    // update the state here using addTodo action
    // action only receive one parameter, which is payload
    dispatch(addTodo(text));
    setText('');
  };

  return (
    <form onSubmit={addTodoHandler}>
      <input
        type='text'
        value={text}
        onChange={(e) => setText(e.target.value)}
      />
      <button>Add todo</button>
    </form>
  );
}

Заключение

Подводя итог, у нас есть 6 шагов по внедрению Redux Toolkit в наш проект React:

  • Установите Redux Toolkit и пакеты React-Redux.
  • Создать store Redux
  • Включите Redux Store в родительский элемент App.js.
  • Создайте фрагмент состояния Redux
  • Добавьте reducer срезов в store
  • Реализация useSelector и useDispatch в компонентах React