使用Redux Reselect过滤注释

时间:2018-06-05 16:55:20

标签: javascript reactjs redux reselect

我试图过滤并显示其帖子ID为'与当前帖子ID匹配。我使用Redux/Reselect,它可以正常工作,但有时会返回错误,指出post._id未定义/ null ..

以下是代码:

const getAllComments = state => state.comments.comments;
const getPost = state => state.posts.post;

export const getCommentsByPostID = createSelector([ getAllComments, getPost ], (comments, post) => {
  return comments.filter((c) => c.postID == post._id);
})

我在getComments()之后在componentDidMount内呼叫getPost(params.id)。 如何确定帖子是否已定义?我应该调用in render方法吗?

1 个答案:

答案 0 :(得分:1)

因此,在调用选择器之前,必须确保您的数据(postscomments)已被提取并可供您使用。

您可以尝试以下流程,以后再尝试(如果适用),可以对其进行改进:

  1. 对于每个实体(PostComment等),您将保留一个名为fetching的新元属性。使用此属性,您将始终知道数据的当前状态。同样,这将防止您对同一资源进行多个API调用(假设您有两个组件,这些组件需要并获取帖子,因此仅应调用1个API请求)。它将具有三个可能的值:

    1. not-started-数据未启动,没有触发数据获取请求。
    2. fetching-正在获取数据。
    3. fetched-数据已被提取。
  2. componentDidMount中,您将调用API调用(动作创建者),这将分别更改fetching状态。

  3. 最后一步是在mapStateToProps中,只有在获取数据的情况下,您才会调用选择器,诸如此类:
const isFetching = entity => ['not-started', 'fetching'].includes(entity.fetching)

const mapStateToProps = state => {
  // Here you wait your data to be fetched,
  // and return `isFetching` flag, in order to show a <Loader /> component,
  // or something else
  if (isFetching(state.posts) || isFetching(state.comments)) return { isFetching: true }

  // Here the data is already fetched, and you can call your selectors.
  return {
   comments: state.comments,
   posts: state.posts
  }
}

这就是我在项目中使用的流程。正如我已经说过的那样,您可以以一种非常基本的方式开始实现它,以后(如果适合)您可以创建一些抽象,这些抽象将减少样板代码。例如-您可以创建一个HOC,仅在其中传递所需的Entities,并且在提取Entities后,HOC将呈现您的组件。诸如此类:DataProviderHOC(PostsList, ['Post', 'Comment'])。仅在提取PostsList个实体的情况下,Post, Comment组件才会呈现。尽可能简单干净。