【发布时间】:2020-06-28 01:30:02
【问题描述】:
我有一个子组件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 组件会在状态或道具更改时重新渲染。
我从两个父组件渲染子组件PostItem:Posts 和Comment。
如果PostItem 是从Posts 渲染的,触发动作likePost 将自动重新渲染组件。这是有道理的,因为我的 redux 状态更改会导致重新渲染。此外,由于 redux 状态作为 props 传递给PostItem,因此更改 redux 状态会更改 props,这也会触发重新渲染。
但是,当PostItem 从Comment 渲染时,触发likePost 不会导致PostItem 重新渲染,即使likePost 操作仍会更改我的redux 状态。我可以在 redux 开发者工具中看到状态实际上已经改变了,但是没有触发重新渲染。在这种情况下,redux 状态也作为 props 传递给 PostItem,但 props 的变化不会触发重新渲染。
为什么PostItem在Posts父组件中重新渲染,而不是Comment父组件? Posts 和 Comment 都将一个 post 对象(包含我的 redux 状态)作为道具传递给 PostItem。
根据网上的建议,我的 reducer 使用扩展运算符来避免使用相同的对象引用。 Posts 和 Comment 都使用相同的操作来更改我的 redux 状态,这意味着在两种情况下状态都在变化。 Posts 和 Comment 都将 redux 状态作为 props 传递给 PostItem,这意味着 props 在这两种情况下都会被更改。
对于完整的可重现代码,我不确定如何继续,因为它 涉及访问数据库,需要我的数据库 URI 以及 JSON 秘密网络令牌。就如何提供最小的建议, 请提供可重现的示例。
我的回购链接:https://github.com/boxcarcoder/ExplorersConnect
请在
reprex分支中查看最小版本的 以下文件:PostItem、Posts 和 Comment 组件:explorersConnect/client/src/components/posts
动作:explorersConnect/client/src/actions
reducers:explorersConnect/client/src/reducers
【问题讨论】:
-
如何在 Stack Snippets 中包含 redux action 和 reducer?以及多个 JS 文件(每个用于一个 React 组件)?我只看到一个用于 HTML、CSS 和 JS 的窗口,看起来每个文件类型都有一个文件。我已经简化了 PostItem、Posts 和 Comment 组件,以及 post action 和 reducer,但不确定是否需要或如何将所有后端代码包含在 Stack Snippet 中。一个指向我的仓库的链接就足够了吗?
-
使用codesandbox或stackblitz
标签: javascript reactjs redux react-redux state