Давайте рассмотрим простое приложение-счетчик. У нас будет кнопка для увеличения счетчика, кнопка для его уменьшения, форма для ввода любого целого числа и кнопка для добавления этого значения в счетчик. В ходе работы над этим проектом мы сфокусируемся и выделим структуру приложения, чтобы получить представление об эффективном способе соединения всех частей.

Давайте начнем с использования create-react-app, и мы будем использовать шаблон Redux, который настроит для нас наш простой проект счетчика.

npx create-react-app learning-react-the-basics --template redux

Найдите время, чтобы просмотреть структуру папок в приложении. Некоторые важные файлы: app / store.js, features / counter / counterSlice.js и features / counter / Counter.js.

// ...src/app/store.js
import { configureStore } from '@reduxjs/toolkit';
import counterReducer from '../features/counter/counterSlice';
export default configureStore({
    reducer: {
        counter: counterReducer,
    },
});

Функция configureStore, предоставляемая нам через Redux Toolkit, принимает в качестве аргумента объект-редуктор. Прямо сейчас он использует counterReducer. Давайте посмотрим, что это такое:

// .../src/features/counter/counterSlice.js
import { createSlice } from '@reduxjs/toolkit';
export const counterSlice = createSlice({
    name: 'counter',
    initialState: {
        value: 0,
    },
    reducers: {
        increment: state => {
            state.value += 1;
        },
        decrement: state => {
            state.value -= 1;
        },
        incrementByAmount: (state, action) => {
            state.value += action.payload;
        },
    },
});
export const { increment, decrement, incrementByAmount } = counterSlice.actions;
export default counterSlice.reducer;

Прежде всего, мы проигнорируем функции преобразователя и селектора в нижней части нашего файла.

Теперь экспорт этого файла по умолчанию - это функция-редуктор для нашей логики счетчика. Это именно то, что мы импортируем в нашу функцию store.js. Вернемся и посмотрим поближе:

// ...src/app/store.js
export default configureStore({
    reducer: {
        counter: counterReducer,
    },
});

Выше, когда мы настраиваем наш магазин, мы передаем объект {counter: counterReducer} в качестве редуктора. Этот объект говорит, что нам нужен раздел счетчика нашего глобального состояния Redux (state.counter), и мы хотим, чтобы counterReducer контролировал, как он обновляется, когда мы отправляем ему действие.

Ладно, имеет смысл. Теперь, оглядываясь назад на наш файл counterSlice.js, у меня возникает вопрос: что такое H «срез»? Redux Slice - это набор логики и действий редуктора для одной функции нашего приложения. Название «срез» происходит от идеи, что мы разделяем корневой объект состояния Redux на несколько «срезов» сланца. Вы когда-нибудь слышали о разделении забот? Святой…

Например, в нашем приложении для управления классами джиу-джитсу настройка магазина может быть примерно такой:

import { configureStore } from '@reduxjs/toolkit'
import usersReducer from '../features/users/usersSlice'
import submissionsReducer from '../features/submissions/submissionsSlice'
import topicsReducer from '../features/topics/topicsSlice'
export default configureStore({
    reducer: {
        users: usersReducer,
        submissions: submissionsReducer,
        topics: topicsReducer
    }
});

Здесь state.users, state.submissions и state.topics - каждая отдельная часть состояния Redux. поскольку usersReducer отвечает только за обработку среза state.users, мы можем называть его нашей функцией «редуктора среза».

Надеюсь, это поможет вам начать изучение и понимание редукторов и фрагментов в Redux!