Существует широкая терминология, которую часто использует экосистема Redux. Мы постараемся охватить самые распространенные из них.

В основе Redux лежат действия, поэтому давайте углубимся в тему.

Структура действий

Действия — это просто все интерактивные действия, которые пользователь может выполнять в приложении или на веб-странице. Это объекты Javascript с двумя свойствами (тип, полезная нагрузка). Вы можете думать о них как об инструкциях для операторов.

// Example 1
{
type: 'categories/addNewCategory',
payload: {
  id: 1,
  title: 'Hats',
  items: [],
  },
}
// Example 2
{
type: 'todos/addNewTodo',
payload: 'Complete homework by Monday',
}

Тип – это строка, представляющая действие, предпринятое пользователем. Он имеет структуру («domain/actionType»). Домен описывает, какому редьюсеру принадлежит действие. Вторая часть строки написана в соответствии с соглашением об имени регистра верблюдов в последнем Redux Toolkit.

полезная нагрузка может быть чем угодно, что нужно отправить редуктору для замены некоторых значений в хранилище. Как показано в приведенных выше примерах, это может быть объект, строка или число. Магазин представляет состояние приложения.

Отправка действий с помощью useDispatch()

Отправка означает отправку действия в пути для замены некоторых значений в магазине. Функция useDispatch() используется для отправки действий, предпринимаемых пользователем, как показано ниже. Пользователь может выполнить два действия (добавить элемент, удалить элемент), нажав кнопки в примере ниже. Когда пользователь нажимает эти кнопки, соответствующее действие будет отправлено в избыточность.

const CartItem = ({ item }) => {
  const dispatch = useDispatch();
  return (
      <div className='item-buttons'>
        <button onClick={() => dispatch(addItemToCart(item))}>Add Item</button>
        <button onClick={() => dispatch(deleteItemFromCart(item))}>Delete Item</button>
      </div>
    </div>
  );
};

Что такое магазин?

Вы можете думать о хранилище как о складе для вашего приложения. Хранилище — это объект, который содержит все динамические состояния, которые вы будете использовать для визуализации своих компонентов. Он начинается с начального состояния и изменяется с течением времени в зависимости от действий, предпринимаемых пользователем. Существует только одно rootState, и несколько подсостояний принадлежат rootState. В приведенном ниже примере есть три подсостояния.

//User
const initialState = {
  currentUser: null,
  isLoading: false,
  error: null,
};

//Categories
const initialState = {
  categories: [],
  isLoading: false,
  error: null,
};

//Cart
const initialState = {
  isCartOpen: false,
  cartItems: [],
};

//Root store will initially look something like this
rootStore = {
  user: {
    currentUser: null,
    isLoading: false,
    error: null,
  },
  categories: {
    categories: [],
    isLoading: false,
    error: null,
  },
  cart: {
    isCartOpen: false,
    cartItems: [],
  }
}
//This store has all the states we need to render our application components

Что такое редукторы?

Редюсеры можно рассматривать как операторы, которые могут распознать отправленное действие и внести необходимые изменения в хранилище. Мы используем функцию createSlice() для определения всех связанных редукторов. Мы создаем пользовательскую часть магазина в примере ниже. В Redux Toolkit есть шаблонный код для настройки вашего магазина Redux. Команда разработчиков определяет и использует лучшие практики для своего подхода, поэтому нам будет полезно соблюдать эти стандартные коды.

const userSlice = createSlice({
  name: 'user', //this defines the domain part of the action
  initialState,
  reducers: {
    checkUserSession(state) {
      state.isLoading = true;
    },
    googleSignInStart(state) {
      state.isLoading = true;
    },
    emailSignInStart(state, action) {
      state.isLoading = true;
    },
    signInSuccess(state, action) {
      state.currentUser = action.payload;
      state.isLoading = false;
      state.error = null;
    },
    signInFail(state, action) {
      state.currentUser = null;
      state.isLoading = false;
      state.error = action.payload;
    },
  },
});