Как структурировать нормализованное хранилище Redux при загрузке данных

1

Я пытаюсь создать приложение 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',
      ...
    }
  },
  ...
}

Но это, по-видимому, немного умаляет читаемость/интуитивность государства. Есть ли лучший способ структурировать состояние?

Теги:
redux

1 ответ

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'
      }
    }
  }
}

Таким образом, я считаю, что разделение вашего реляционного состояния на дочерний объект сущностей, в то время как разделы, относящиеся к конкретным страницам, работают хорошо для меня.

  • 0
    Я планировал, чтобы приложение складывало несколько книг друг над другом (StackNavigator), чтобы реагировать на нативные. В результате я не думаю, что у меня может быть один глобальный isLoading, поскольку пользователь пытается загрузить одну книгу, а затем перейти к другой, пока первая еще загружается?
  • 0
    Как я уже упоминал в своем ответе, если вам нужна такая степень детализации, вы можете сделать несколько вещей, например, сохранить набор идентификаторов, которые находятся в состоянии загрузки, в отдельной части дерева состояний. Хотя лучшим решением будет сохранить карту от идентификатора до объекта состояния, который может включать в себя, загружается ли он, есть ли какие-либо ошибки и так далее. Опять же, я бы выделил реляционное состояние и поместил бы это состояние пользовательского интерфейса в отдельную часть вашего дерева. Надеюсь, это даст более четкий ответ!
Показать ещё 4 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню