iron-1920-1080-wallpaper

Теперь начнем разбираться в том как, мы работаем с данными. Пока, для отображения статей мы использовали денормализированную структуру. Ее видно в файле fixtures.js. В каждой статье есть вся информация о ней, она напоминает древовидную структуру. Подобная структура удобна для чтения, но она превратит вашу жизнь в ад если вы начнете как-то изменять эти данные. Если у вас будет более или менее сложная структура, где эти зависимости будут пересекаться, например, у статьи есть автор у комментария есть автор, у автора есть своя страница. Если хранить это в том виде как это есть сейчас, то когда вы захотите поменять имя этого автора, вам придется просмотреть все места где даже чисто теоретически он может использоваться и заменить эти данные, и скорее всего Вы что-то пропустите. Поэтому, перед тем как сохранять данные в stores их нормализируют. Нужно отдельно хранить сущности комментариев, статей, авторов и.т.п, и отдельно хранить связи (например у статьи есть много комментариев), в виде id.

На клиенте удобно хранить данные в одном месте, к примеру, там где много комментариев, там сразу можно хранить массив с id этих комментариев. Это довольно удобно, так как все манипуляции с нашими данными можно будет делать в одномreducer. Давайте реализуем такую структуру. Сделаем reducer для комментариев, для этого в папке reducer создадим файл comments.js:

import {  } from '../constants'

export default (comments = {}, action) => {
    const { type, payload, response, error } = action

    switch (type) {

    }

    return comments
}

Также мы немного изменим то, как мы храним данные, сейчас мы храним их в виде обычного массива, и это не очень удобно, если мы хотим работать с данными. Нам часто нужно обращаться к конкретному элементу, поэтому будет удобнее хранить данные в виде объектов, ключами в которых выступают id (статьи например), а их значением будет сама статья. Таким образом мы значительно упростим обращение к элементам нашего store.  Давайте все это перестроим и начнем с reducer/articles.js. В articles мы будем уже брать normalizedArticles, изменим import следующим образом:

import { normalizedArticles } from '../fixtures'

Также в reducer/comments.js добавим import:

import { normalizedComments } from '../fixtures'

Продолжим наш урок с использованием библиотеки immutable.js. Установим ее:

Read More:  15. Уроки Node.js. Асинхронная разработка. Введение.

npm i immutable --s

У immutable.js есть разные структуры данных, одна из самых часто используемых List, это аналог массива, просто immutable. Map это аналог объекта.OrderedMap– это вариация Mapгде вы сохраняете последовательность в которой были добавлены элементы. И еще есть такой элемент Record, в который позволяет описать вид в котором у Вас находится элемент. Давайте используем  Record и OrderedMap в нашем проекте.  Сделаем следующие  записи в reducer/articles.js:

import { normalizedArticles } from '../fixtures'
import { DELETE_ARTICLE } from '../constants'
import { OrderedMap, Record } from 'immutable'


const Article = Record({
    "id": "",
    "date": "",
    "title": "",
    "text": "",
    "comments": []
})

const defaultArticles = normalizedArticles.reduce((acc, el) => {
    return acc.set(el.id, new Article(el))
}, new OrderedMap({}))

export default (articles = defaultArticles, action) => {
    const { type, payload } = action

    switch (type) {
        case DELETE_ARTICLE:
            return articles.filter(article => article.id != payload.id)
    }
    return articles
}

В переменной defaultArticles мы с Вами идем по массиву normalizedArticles и с помощью метода reduce проходим от первого до последнего элемента  массива, собирая их в какую-то другую структуру, в нашем случает в immutabele объект acc, также здесь есть  el – это элемент к которому мы сейчас обращаемся (первая статья, вторая статья и т.д.). И начальное значение acc, то с которого мы начинаем – new OrderedMap({})).  Возвращаем мы с Вами:

acc.set(el.id, new Article(el))

В константе  const Article вы описываете то, какого вида у Вас статьи. В нашем случае мы указываем default значения для статей. Все записи будут храниться в таком виде. В данном случае можно было воспользоваться и обычными объектами и методом mapи тогда нечего особенно для Вас не поменяется. Но Record придуман именно для подобных записей. У Вас появляется гарантированная структура Ваших данных (статей) и она будет всегда выдержана . Также будет удобнее обращаться к immutabele объекту article, к примеру при использовании простого объекта будет выглядеть так:
article.get('title'), если мы используем Record,  у нас уже есть готовый getter и мы сможем просто обращаться:article.title.

Далее нужно будет немного поменять наш API, перейдем в containers/Filters.js и сделаем следующие изменения:

export default connect(state => {
    const { articles, filters } = state
    return {
        articles: articles.valueSeq(),
        filters
    }
}, { changeFilters

Раньше мы рассчитывали что будем работать с массивом, а сейчас мы получаем объект. Поэтому мы преобразуем его в connect. Для того чтобы превратить структуру  OrderedMapв массив  List мы вызываем метод valueSeq() таким образом у нас получится просто массив статей.

Read More:  Уроки React. Урок 13. Часть 2.

Также у нас могут быть проблемы в select, т.к. мы ожидали что в нем у нас приходит массив, а теперь мы получаем custom structure.  Чтобы ошибок не произошло необходимо пойти в атрибуту options превратив их в toJS():

                <Select
                    options = {options.toJS()}
                    multi = {true}
                    value = {filters.selectedArticles}
                    onChange = {this.handleSelectChange}
                />

Также необходимо будет исправить containers/Articles.js:

function filterArticles(articles, { from, to, selectedArticles }) {
    return articles.valueSeq()

Почему мы вызываем valueSeq()? Потому, что articles – это объект (ключ : значение), а мы хотим достать из него значения и поместить их в массив. Аналогично этому есть также keySeq , для того чтобы достать ключи. Дальше преобразовывать ничего не надо, так как React прекрасно понимает immutable.js, и его структуры. Поэтому не надо переводить их в нативные JS структуры.

Код урока вы можете найти в нашем репозитории.

to_be_continued

We are looking forward to meeting you on our website blog.soshace.com

Share.
Leave A Reply
Privacy Overview

This website uses cookies so that we can provide you with the best user experience possible. Cookie information is stored in your browser and performs functions such as recognising you when you return to our website and helping our team to understand which sections of the website you find most interesting and useful.