You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React 规范化Redux store场景下应在哪里查询状态?

你可以采用展示组件+容器组件分离的成熟模式,同时兼顾两类场景的需求,不需要牺牲任何一方的体验。

具体实现方案

将同一个组件拆为两层:

  1. 纯展示层:无任何Redux依赖,所有渲染所需数据都通过props传入,专门用于测试、Storybook场景
  2. 容器层:仅负责对接Redux Store获取数据,把取到的参数透传给展示组件,业务开发时直接调用容器组件即可

示例代码

Comment组件拆分
// 纯展示组件:无store依赖,参数清晰,方便测试和写Storybook
export const Comment = ({ username, date, title, content }) => {
  return (
    <div>
      <p>{username}@{date}</p>
      <em>{title}</em>
      <p>{content}</p>
    </div>
  );
};

// 容器组件:仅负责对接store,业务代码直接调用这个版本
export const ConnectedComment = ({ commentId }) => {
  const comment = useSelector(state => selectComment(state, commentId));
  return <Comment {...comment} />;
};
PostView组件拆分
// 纯展示组件
export const PostView = ({ title, content, comments }) => {
  return (
    <>
      <h1>{title}</h1>
      <p>{content}</p>
      {comments?.map(comment => <Comment key={comment.id} {...comment} />)}
    </>
  );
};

// 容器组件
export const ConnectedPostView = ({ postId }) => {
  const post = useSelector(state => selectPost(state, postId));
  // 批量获取关联评论,不要在循环内调用useSelector
  const comments = useSelector(state => 
    post.comments?.map(commentId => selectComment(state, commentId)) ?? []
  );
  return <PostView {...post} comments={comments} />;
};

方案优势

  • 业务开发体验和你提到的「新方案」完全一致,仅需要传入id即可,组件自动获取所有关联数据,数据变更时仅对应组件重渲染的性能优势也完全保留
  • 测试和Storybook场景直接调用纯展示组件,不需要mock Redux Store,也保留了直接修改props调试的能力
  • 彻底规避了你尝试的「混合方案」中「在循环内调用Hook」的语法错误

可选优化

如果担心批量查询评论导致不必要的重渲染,可以用Reselect创建带缓存的聚合Selector,仅当Post或者关联的Comment数据变更时才返回新值:

import { createSelector } from '@reduxjs/toolkit';

const selectPostWithComments = createSelector(
  [selectPost, selectAllComments],
  (post, allComments) => {
    if (!post) return null;
    return {
      ...post,
      comments: post.comments?.map(id => allComments.find(comment => comment.id === id)) ?? []
    };
  }
);

如果组件逻辑非常简单,不想拆分两个组件,也可以做参数兼容:传入id就从store取数据,否则直接用传入的props,不过这种方式不如拆分清晰,优先推荐分层方案。

内容的提问来源于stack exchange,提问作者Newlukai

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 07:45:03