加载数据时如何构造规范化的Redux存储

时间:2017-08-07 01:49:05

标签: javascript redux

我正在尝试创建一个列出书籍的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',
      ...
    }
  },
  ...
}

但这似乎略微偏离了国家的可读性/直觉性。有没有更好的方法来构建国家?

1 个答案:

答案 0 :(得分:1)

我构建了我的redux存储,以便它包含所有关系数据的实体对象,并且我将特定于页面的东西或一组路由存储在状态的不同部分中。我的状态树可能看起来像这样:

const state = {
  entities: {
    books: {
      ...
    },
    authors: {
      ...
    },
    ...
  },
  booksPage: {
    isLoading: false
  }
} 

现在我跟踪我的关系状态与UI组件的状态分开。我不建议尝试将isLoading状态存储在单个实体中,因为该实体可能存在也可能不存在。如果您需要基于每个实体更精细的加载/错误状态,那么您可以选择一组实体。第一个选项是保留当前正在加载的一组ID。这不是一个非常实用的解决方案,因为您无法通过ID在集合中跟踪成功或失败。

下一个更好的解决方案是将地图从ID保存到状态对象,该状态对象包括单个实体是否正在加载,是否成功或者加载失败以及错误是什么。

const state = {
  entities: {
    books: {
      ...
    },
    authors: {
      ...
    },
    ...
  },
  booksPage: {
    loading: {
      book1: {
        status: 'FAILED',
        error: 'Network request failed.'
      },
      book2: {
        status: 'SUCCESS',
      },
      book3: {,
        status: 'IN_PROGRESS'
      }
    }
  }
}

总之,我发现将关系状态分离为实体子对象,同时具有特定于页面的状态部分对我来说非常有效。