Дочерний компонент не выполняет повторную визуализацию от изменения состояния одного родителя, но выполняет повторную визуализацию от другого родителя - PullRequest
0 голосов
/ 17 марта 2020

У меня есть дочерний компонент PostItem, который принимает пост-объект из избыточного состояния в качестве реквизита:

const PostItem = ({
      post: { _id, text, name, avatar, user, likes}, //from redux state
      //...
   }) => {

   //...

   const handleLike = e => {
      likePost(_id); //ACTION
   };

   return (
      <Fragment>
        <div className='post bg-white vert-m-1 p-1'>
          <div>
            <p className='vert-m-1'>{text}</p>
            <button className='btn' onClick={e => handleLike(e)}>
              <i className='fas fa-thumbs-up'></i> <span>{likes.length}</span>
            </button>
        </div>
      </Fragment>
   );
}

У меня есть действие likePost, которое изменяет состояние в reducer:

    case LIKE_A_POST:
    case UNLIKE_A_POST:
      return {
        ...state,
        posts: state.posts.map(post =>
          post._id === payload.id
            ? {
                ...post,
                likes: payload.likes 
              }
            : post
        ),
        loading: false
      };

Насколько мне известно, компонент React перерисовывается при изменении состояния или реквизита.

Я рендерим дочерний компонент PostItem из 2 родительских компонентов: Posts и Comment ,

Если PostItem отображается из Posts, запуск действия likePost автоматически повторно выполнит визуализацию компонента. Это имеет смысл, потому что мои изменения состояния редукса приведут к повторному рендерингу. Кроме того, поскольку состояние избыточности передается как реквизит на PostItem, изменение состояния избыточности изменит реквизит, который также вызывает повторную визуализацию.

Однако, когда PostItem отображается с Comment, запуск likePost не вызывает повторного рендеринга PostItem, даже если действие likePost все еще меняет мое состояние притока. Я вижу в инструментах разработчика излишков, что состояние фактически изменилось, но повторное рендеринг не запускается. В этом случае состояние избыточности также передается как реквизит PostItem, но изменение реквизита не вызывает повторного рендеринга.

Почему PostItem повторный рендеринг в Posts родительский компонент, но не Comment родительский компонент? И Posts, и Comment передают постобъект (содержащий мое состояние редукса) в качестве реквизита PostItem.

Следуя советам онлайн, мой редуктор использует оператор распространения, чтобы избежать использования одной и той же ссылки на объект. И Posts, и Comment используют одно и то же действие для изменения моего избыточного состояния, то есть состояние меняется в обоих случаях. И Posts, и Comment передают состояние редукса как реквизит PostItem, что означает, что реквизиты меняются в обоих случаях.

Для полностью воспроизводимого кода я не уверен, как продолжайте, поскольку он включает в себя доступ к базе данных, требующий URI моей базы данных, а также JSON Secret Web Token. Посоветуйте, как предоставить минимальный воспроизводимый пример, пожалуйста.

Ссылка на мой репо: https://github.com/boxcarcoder/ExplorersConnect

Пожалуйста, посмотрите в ветке reprex минимальный версия следующих файлов:

Компоненты PostItem, Posts и Comment: explorersConnect / client / src / components / posts

Действия: explorersConnect / client / src / actions

Редукторы: explorersConnect / client / src / redurs

1 Ответ

0 голосов
/ 17 марта 2020

Ключ к пониманию того, что хотя likePost изменяет likes сообщения, это сообщение не является состоянием post избыточного, а является сообщением в состоянии posts избыточного массива. Это означает, что запуск likePost вызывает изменение на posts, которое является опорой для Posts, но не Comment. Неправильное предположение заключалось в том, что изменение Posts будет изменением состояния, которое вызывает Comment для повторной визуализации, но реквизиты Comment не изменяются, поэтому повторной визуализации не происходит.

Поскольку Comment 's реквизиты post, действие likePost и редуктор должны изменить post в состоянии избыточности, так что изменение реквизита и состояния вызовет повторный рендеринг Comment.

Между изменением состояния была путаница: изменение state.posts - это не то же самое, что изменение state.post, хотя теоретически state.posts - это просто массив всех state.post с. Ключ в понимании того, что изменение в компоненте Props необходимо, а не просто изменение состояния. Изменение состояния должно напрямую влиять на свойства компонента.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...