Структура состояния JS: Redux (React)

Данный урок базируется на статье https://redux.js.org/recipes/structuring-reducers/normalizing-state-shape из официальной документации

Большинство приложений работают с данными, которые имеют вложенную структуру. Например, у постов в блоге есть автор и комментарии. У комментариев тоже есть авторы и могут быть лайки.

const blogPosts = [
  {
    id: 'post1',
    author: { username: 'user1', name: 'User 1' },
    body: '......',
    comments: [
      {
        id: 'comment1',
        author: { username: 'user2', name: 'User 2' },
        comment: '.....'
      },
      {
        id: 'comment2',
        author: { username: 'user3', name: 'User 3' },
        comment: '.....'
      }
    ]
  },
];

Работать с такой структурой напрямую тяжело по нескольким причинам:

  • Внутри неё дублируются данные, например, author. Из-за этого резко усложняется обновление.
  • Логика редьюсеров становится тем сложнее, чем больше вложенность

Правильный подход при работе с Redux — воспринимать его как реляционную базу данных. Данные внутри контейнера должны быть нормализованы. При таком взгляде каждый редьюсер может восприниматься как отдельная таблица в базе данных.

Основные принципы организации данных в контейнере:

  • Каждая сущность хранится в своём редьюсере.
  • Коллекция сущностей одного типа хранится в виде объекта, где ключи — идентификаторы объектов, а значения — сами объекты.
  • Порядок данных в этом объекте задаётся отдельным массивом состоящим только из идентификаторов.
  • Данные ссылаются друг на друга только по идентификаторам.
{
    posts : {
        byId : {
            "post1" : {
                id : "post1",
                author : "user1",
                body : "......",
                comments: ["comment1", "comment2"],
            },
            "post2" : {
                id : "post2",
                author : "user2",
                body : "......",
                comments: [],
            }
        },
        allIds : ["post1", "post2"]
    },
    comments : {
        byId : {
            "comment1" : {
                id : "comment1",
                author : "user2",
                comment : ".....",
            },
            "comment2" : {
                id : "comment2",
                author : "user3",
                comment : ".....",
            }
        },
        allIds : ["comment1", "comment2"]
    },
    users : {
        byId : {
            "user1" : {
                username : "user1",
                name : "User 1",
            },
            "user2" : {
                username : "user2",
                name : "User 2",
            },
            "user3" : {
                username : "user3",
                name : "User 3",
            }
        },
        allIds : ["user1", "user2", "user3"]
    }
}

Теперь данные нормализованы. Каждая сущность хранится в своём собственном редьюсере. Объект byId хранит сами сущности, а allIds - идентификаторы. Какие преимущества мы получили?

  • Данные не повторяются, а значит достаточно поменять только одно место при их изменении
  • Редьюсеры не имеют вложенности
  • Данные в таком виде легко извлекать и модифицировать

<span class="translation_missing" title="translation missing: ru.web.courses.lessons.mentors.mentor_avatars">Mentor Avatars</span>

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят команда поддержки Хекслета или другие студенты.

Ошибки, сложный материал, вопросы >
Нашли опечатку или неточность?

Выделите текст, нажмите ctrl + enter и отправьте его нам. В течение нескольких дней мы исправим ошибку или улучшим формулировку.

Что-то не получается или материал кажется сложным?

Загляните в раздел «Обсуждение»:

  • задайте вопрос. Вы быстрее справитесь с трудностями и прокачаете навык постановки правильных вопросов, что пригодится и в учёбе, и в работе программистом;
  • расскажите о своих впечатлениях. Если курс слишком сложный, подробный отзыв поможет нам сделать его лучше;
  • изучите вопросы других учеников и ответы на них. Это база знаний, которой можно и нужно пользоваться.
Об обучении на Хекслете

Для полного доступа к курсу нужна профессиональная подписка

Профессиональная подписка откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.

Получить доступ
120
курсов
900
упражнения
2000+
часов теории
3200
тестов

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно.

  • 120 курсов, 2000+ часов теории
  • 900 практических заданий в браузере
  • 360 000 студентов

Отправляя форму, вы соглашаетесь c «Политикой конфиденциальности» и «Условиями оказания услуг».

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Rambler
Логотип компании Bookmate
Логотип компании Botmother

Рекомендуемые программы

С нуля до разработчика. Возвращаем деньги, если не удалось найти работу.

Иконка программы Фронтенд-разработчик
Профессия

Фронтенд-разработчик

Разработка фронтенд-компонентов веб-приложений
23 июня 8 месяцев

Есть вопрос или хотите участвовать в обсуждении?

Зарегистрируйтесь или войдите в свой аккаунт

Отправляя форму, вы соглашаетесь c «Политикой конфиденциальности» и «Условиями оказания услуг».