До 30 ноября

Скидки до 81 000 руб и вторая профессия в подарок!

Главная | Все статьи | Дневник студента

Redux для самых маленьких: как создать свою библиотеку

Время чтения статьи ~3 минуты
Статья написана студентом Хекслета. Мнение автора может не совпадать с позицией редакции
Redux для самых маленьких: как создать свою библиотеку главное изображение

Всем привет!

Этой мой первый пост в дневнике, и посвящён он библиотеке Redux.

За время моего обучения на Hexlet именно эта библиотека породила кучу вопросов а-ля -'как это работает, почему это так работает ?'. Несколько дней я перечитывал теорию по Redux, но в голове не укладывалось, пока я не написал свою собственную версию Redux.

Предлагаю вам вместе со мной написать свою версию библиотеки, просто чтобы разобраться как это работает "под капотом".

В Redux ядром всего является объект store, который возвращает нам функция createStore(). Поэтому давайте начнём с создания этой функции.

Согласно документации createStore принимает первым аргументов функцию reducer, а вторым начальное состояние.

const createStore = (reducer, initialState) => {
  let state = reducer(initialState, { type: '__INIT__' });
  let subscribers = [];

  return {
    dispatch(action) {
      state = reducer(state, action);
      subscribers.forEach((cb) => cb());
    },
    subscribe(cb) {
      subscribers = [...subscribers, cb];
    },
    getState() {
      return state;
    },
  };
};

Сначала инициализируем state начальными данными.

let state = reducer(initialState, { type: '__INIT__' });

Функцию reducer мы напишем позже, но главное понимать, что функция возвращает измененный или неизменённый state.

Функция createStore должна вернуть объект store со следующими методами: dispatch(), subscribe(), getState().

getState() просто возвращает текущий state.

subscribe() принимает в качестве аргумента callback-функцию и складывает функцию в массив.

dispatch() принимает в качестве аргумента объект. Этот объект может иметь внутри любые поля и данные, но в обязательном порядке должен иметь поле type. Например { type: 'ADD' }. Когда вызывается метод dispatch(), то state должен быть изменен через reducer. Reducer - это функция, внутри которой данные меняются, в зависимости от описанной внутри логики. После того, как state был изменен, нам нужно последовательно вызвать все callback-функции, которые были добавлены в массив посредством метода subscribe().

Теперь создаем функцию reducer, которая согласно внутренней логики будет менять состояние.

const ourReducer = (state, action) => {
  switch(action.type) {
    case 'INC':
      return state + 1;
    case 'DEC':
      return state - 1;
    default:
      return state;
  }
};

Здесь все должно быть понятно. Функция принимает объект action с полем type. Например { type: 'INC }. В зависимости от значения поля type отрабатывает switch-case конструкция и происходит возврат состояния.

Дальше создаем объект store, интерфейсами которого и будем манипулировать.

const store = createStore(ourReducer, 0);

Теперь попробуем вызвать методы нашего хранилища store. Для начала мы хотим чтобы при изменении нашего состояния в console автоматически печаталось текущее состояние.

store.subscribe(() => console.log(store.getState())); 

Теперь вернем текущее состояние

store.getState(); // -> вернётся 0, так как это начальное состояние.

Теперь изменим наше состояние методом dispatch(), который внутри вызывает редьюсер, меняющий состояние, и вызывает последовательно все callback функции из массива subscribers.

store.dispatch({ type: 'INC' }); // -> в консоле будет 1
store.dispatch({ type: 'INC' }); // -> в консоле будет 2
store.dispatch({ type: 'DEC' }); // -> в консоле будет 1 

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

Ниже представлен полный код для удобства копирования в свой редактор:

const createStore = (reducer, initialState) => {
  let state = reducer(initialState, { type: '__INIT__' });
  let subscribers = []; 

  return {
    dispatch(action) {
      state = reducer(state, action);
      subscribers.forEach((cb) => cb());
    },
    subscribe(cb) {
      subscribers = [...subscribers, cb];
    },
    getState() {
      return state;
    },
  };
};

const ourReducer = (state, action) => {
  switch(action.type) {
    case 'INC':
      return state + 1;
    case 'DEC':
      return state - 1;
    default:
      return state;
  }
};

const store = createStore(ourReducer, 0);

store.subscribe(() => console.log(store.getState())); 
store.getState(); 
store.dispatch({ type: 'INC' }); 
store.dispatch({ type: 'INC' }); 
store.dispatch({ type: 'DEC' }); 
Аватар пользователя Виталий Моржов
Виталий Моржов 07 октября 2022
1
Рекомендуемые программы
профессия
Осваивайте разработку веб-страниц, оживляйте дизайн макетов, публикуйте сайты и приложения. Отслеживайте ошибки в интерфейсе и устраняйте их
10 месяцев
с нуля
Старт 28 ноября
профессия
Обучитесь разработке бэкенда сайтов и веб-приложений — серверной части, которая отвечает за логику и базы данных
10 месяцев
с нуля
Старт 28 ноября
профессия
Выполняйте ручное тестирование веб-приложений, находите ошибки в продукте. Узнайте все о тест-дизайне.
4 месяца
с нуля
Старт 28 ноября
профессия
Научитесь разработке веб-приложений, сайтов и программного обеспечения на языке Java, программируйте и используйте структуры данных
10 месяцев
с нуля
Старт 28 ноября
профессия
новый
Собирайте, анализируйте и интерпретируйте данные, улучшайте бизнес-процессы и продукт компании. Обучитесь работе с библиотеками Python
9 месяцев
с нуля
Старт 28 ноября
профессия
Занимайтесь созданием сайтов, веб-приложений, сервисов и их интеграцией с внутренними бизнес-системами на бекенд-языке PHP
10 месяцев
с нуля
Старт 28 ноября
профессия
Создание веб-приложений со скоростью света
5 месяцев
c опытом
Старт 28 ноября
профессия
Обучитесь разработке визуальной части сайта — фронтенда, а также реализации серверной — бэкенда. Освойте HTML, CSS, JavaScript
16 месяцев
с нуля
Старт 28 ноября
профессия
Разработка бэкенд-компонентов для веб-приложений
10 месяцев
с нуля
Старт 28 ноября
профессия
новый
Организовывайте процесс автоматизации тестирования на проекте, обучитесь языку программирования JavaScript, начните управлять процессом тестирования
8 месяцев
c опытом
Старт 28 ноября