我还没有找到一个明确的答案,希望这不是重复.

我正在使用React+Redux作为一个简单的聊天应用程序.该应用程序由输入栏、消息列表和容器组件组成.容器(正如您可能想象的)包装了其他两个组件,并连接到store .我的消息的状态以及当前消息(用户当前键入的消息)保存在Redux存储中.简化 struct :

class ContainerComponent extends Component {
  ...
  render() {
    return (
      <div id="message-container">
        <MessageList 
          messages={this.props.messages}
        />
        <InputBar 
          currentMessage={this.props.currentMessage}
          updateMessage={this.props.updateMessage}
          onSubmit={this.props.addMessage}
        />
      </div>
    );
  }
}

我遇到的问题发生在更新当前消息时.更新当前消息会触发更新存储的操作,该操作会更新通过容器并返回到InputBar组件的props .

这是可行的,但是一个副作用是,每次发生这种情况时,我的MessageList组件都会被重新呈现.MessageList没有收到当前消息,没有任何更新的理由.这是一个大问题,因为一旦消息列表变大,每次更新当前消息时,应用程序都会明显变慢.

我已经try 直接在InputBar组件中设置和更新当前消息状态(完全忽略了Redux架构),并且"修复"了这个问题,但是如果可能的话,我希望继续使用Redux设计模式.

我的问题是:

  • 如果父组件已更新,React是否始终更新该组件中的所有直接子组件?

  • 正确的方法是什么?

推荐答案

如果父组件已更新,React是否始终更新该组件中的所有直接子组件?

否.如果shouldComponentUpdate()返回true,React只会重新渲染组件.默认情况下,该方法总是返回true,以避免新手遇到任何微妙的错误(正如William B所指出的,DOM实际上不会更新,除非发生更改,从而降低影响).

为了防止子组件不必要地重新渲染,需要以这样的方式实现shouldComponentUpdate方法:当数据实际发生更改时,它只返回true.如果this.props.messages始终是同一个数组,则可以简单如下:

shouldComponentUpdate(nextProps) {
    return (this.props.messages !== nextProps.messages);
}

您可能还想对消息ID或其他东西进行某种深度比较,这取决于您的需求.

编辑:几年后,许多人开始使用功能组件.如果你是这样的话,那么你会想签React.memo.默认情况下,功能组件每次都会重新渲染,就像类组件的默认行为一样.要修改该行为,可以使用React.memo()并可选地提供areEqual()函数.

Reactjs相关问答推荐

自动化幻灯片放映以防止React中重复过多的正确方法是什么

实时收听react前端应用程序中的webhook响应

在带有和设计的表格中禁用和取消选中复选框

react 派生状态未正确更新

CreateBrowserRouter将props 传递给父组件以验证权限

Redux向后端发送请求时出现钩子问题

如何在取数后添加新数据,并在页面上保存旧数据?

cypress 不能点击SPAN

两条react 路由的行为不同.有没有人能解释一下,我已经找了好几天了

为什么我的react虚拟化列表不显示滚动条,除非我确保高度低于rowCount*rowHeight?

如何在与AntD的react 中限制文件上传和显示消息?

Gitlab CI和VITE环境变量出现问题

错误:无法获取 RSC 负载.返回浏览器导航

如何实现 redux 工具包来注册用户?

react - 警告:列表中的每个子元素都应该有一个独特的 keys props ,即使我已经设置了 keys

React Final Form - 单选按钮在 FieldArray 中不起作用

添加 React/Redux 组件模板的 VS Code 扩展

Mui CardMedia 的图片组件

在嵌套的 Stack Navigator 中的 BottomTabBar 中导航会导致比以前更多的渲染

Storybook - 无法解析generated-stories-entry.cjs/字段browser不包含有效的别名配置