子组件不是从一个父级的状态更改重新渲染,而是从另一父级重新渲染?

时间:2020-03-16 23:16:31

标签: javascript reactjs redux react-redux state

我有一个子组件PostItem,该子组件将来自redux状态的post对象作为道具:

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组件会在状态或道具更改时重新呈现。

我从两个父组件PostItemPosts渲染子组件Comment

如果从PostItem渲染了Posts,则触发动作likePost将自动重新渲染组件。这是有道理的,因为我的redux状态更改了,这将导致重新渲染。另外,由于将redux状态作为道具传递给PostItem,所以更改redux状态将更改道具,这也会触发重新渲染。

但是,从PostItem渲染Comment时,即使likePost动作仍然改变了我的位置,触发PostItem并不会导致likePost重新渲染还原状态。我可以在redux Developer工具中看到状态实际上已更改,但是未触发重新渲染。在这种情况下,也将redux状态作为prop传递给PostItem,但是prop的更改不会触发重新渲染。

为什么在PostItem父组件中而不是在Posts父组件中重新渲染CommentPostsComment都传递一个post对象(包含我的redux状态)作为对PostItem的支持。

根据在线建议,我的化简使用散布运算符来避免使用相同的对象引用。 PostsComment都使用相同的操作来更改我的redux状态,这意味着两种情况下状态都在变化。 PostsComment都将redux状态作为对PostItem的支持,这意味着在两种情况下道具都被更改了。

对于完整的可复制代码,我不确定该如何进行 涉及访问数据库,需要我的数据库URI以及 JSON秘密Web令牌。就如何提供最低限度的建议, 请复制示例。

指向我的仓库的链接:https://github.com/boxcarcoder/ExplorersConnect

请在reprex分支中查看的最低版本 以下文件:

PostItem,Posts和Comment组件:explorersConnect / client / src / components / posts

动作:explorersConnect /客户端/ src /动作

Reducers:explorersConnect /客户端/ src / reducers

1 个答案:

答案 0 :(得分:0)

关键是要认识到,尽管likePost更改了帖子的likes,但该帖子不是post的redux状态,而是posts数组内的帖子还原状态。这意味着触发likePost会触发对posts的更改,这是对Posts的支持,而不是Comment的支持。错误的假设是,更改Posts会导致状态更改,从而触发Comment重新渲染,但是Comment的道具不会更改,因此没有重新渲染。

由于Comment的道具为post,因此likePost的动作和减速器应在还原状态下更改post,以便触发道具和状态的更改重新渲染Comment

更改状态之间存在混淆: 更改state.posts与更改state.post并不相同,尽管从理论上讲state.posts只是所有state.post的数组。关键是要理解,必须更改组件的Props,而不仅仅是状态更改。状态更改必须直接影响组件的道具。