Фильтрация комментариев с помощью Redux Reselect - PullRequest
0 голосов
/ 05 июня 2018

Я пытаюсь отфильтровать и отобразить комментарии, чей 'postID' совпадает с текущим идентификатором поста.Я использую Redux/Reselect, он работает, но иногда он возвращает ошибку, которая говорит, что post._id не определено / пусто ..

Вот код:

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 голосов
/ 25 июня 2018

Поэтому, прежде чем вызывать селекторы, вы должны убедиться, что ваши данные (posts и comments) уже получены и доступны для вас.

Вы можете попробовать следующий поток и позже (если онработает для вас), вы можете улучшить его:

  1. Для каждой сущности (Post, Comment и т. д.) вы сохраните новое мета-свойство с именем fetching,С этим свойством вы всегда будете знать текущее состояние ваших данных.Также это предотвратит несколько обращений API к одним и тем же ресурсам (представьте, что у вас есть два компонента, они требуют и извлекают сообщения, поэтому должен вызываться только 1 запрос API).У него будет три возможных значения:

    1. not-started - данные не запускаются, запрос на выборку данных не запускается.
    2. fetching - данные находятся в процессе обработкиfetched.
    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, где вы будете передавать только необходимые сущности, и HOC будет отображать ваш компонент после извлечения сущностей.Примерно так: DataProviderHOC(PostsList, ['Post', 'Comment']).Компонент PostsList будет отображаться, только если Post, Comment Entities выбраны.Как можно проще и понятнее.

...