Я пытаюсь создать приложение React/Redux, в котором перечислены книги. Каждая книга имеет связанные книги. Я знаю, что я должен структурировать свой магазин redux каким-то нормализованным образом, например:
{
books: {
'book1id': {
title: 'Book 1',
author: 'Author 1',
relatedBooks: ['book2id', 'book3id']
},
'book2id': {
title: 'Book 2',
author: 'Author 2',
relatedBooks: ['book1id']
}
}
}
и загружать каждую книгу по мере необходимости.
Проблема в том, где хранить данные по загрузке/ошибке из запросов API? Некоторые идеи, которые у меня были, заключались в создании объекта для каждой книги, такой как
books: {
'book1id': {
isLoading: false,
error: null,
book: {
title: 'Book 1',
...
}
},
...
}
Но это, по-видимому, немного умаляет читаемость/интуитивность государства. Есть ли лучший способ структурировать состояние?
Я структурирую хранилище редукта, чтобы он включал объект сущности для всех моих реляционных данных, и я хранил вещи, специфичные для страницы или набора маршрутов в отдельных частях состояния. Мое дерево состояний может выглядеть примерно так:
const state = {
entities: {
books: {
...
},
authors: {
...
},
...
},
booksPage: {
isLoading: false
}
}
Теперь я отслеживаю свое реляционное состояние отдельно от состояния компонентов моего интерфейса. Я бы не рекомендовал пытаться сохранить состояние isLoading
в отдельном объекте, поскольку этот объект может существовать или не существовать. Если вам требуется более подробное состояние загрузки/ошибки на основе сущности, а скорее на набор объектов, у вас есть несколько вариантов. Первый вариант - сохранить набор идентификаторов, которые в настоящее время загружаются. Это не очень практичное решение, потому что вы не можете отслеживать успех или неудачу с идентификатором, просто находящимся в наборе или нет.
Следующее лучшее решение состоит в том, чтобы сохранить карту из идентификатора в объект статуса, который включает в себя загрузку отдельного объекта, если он был успешным или если он не смог загрузить и какие были ошибки.
const state = {
entities: {
books: {
...
},
authors: {
...
},
...
},
booksPage: {
loading: {
book1: {
status: 'FAILED',
error: 'Network request failed.'
},
book2: {
status: 'SUCCESS',
},
book3: {,
status: 'IN_PROGRESS'
}
}
}
}
Таким образом, я считаю, что разделение вашего реляционного состояния на дочерний объект сущностей, в то время как разделы, относящиеся к конкретным страницам, работают хорошо для меня.