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

React Hooks 如何在调用setState时将其自身作为prop传递避免卡顿

卡顿根因

你的卡顿问题和传递setState本身无关,核心问题是你直接把React组件实例(

return (<Test />)
)存入了state中,这是React官方不推荐的写法:state仅应该存储可序列化的状态数据,存组件实例会导致React在状态更新时额外处理不必要的组件引用逻辑、重复创建组件实例,拉长渲染链路,最终出现卡顿。
其次Modal打开时一次性渲染5个Tab的全量子组件,也会放大渲染延迟的问题。

修复方案

1. 重构state结构,仅存元数据

删除state中存储的组件实例,只存储渲染需要的参数、标识等纯数据,组件渲染逻辑放到UI层处理:

// 修改state定义,仅存纯数据
const [modalConfig, setModalConfig] = useState({
  title: '',
  modalType: '', // 用来标识当前要渲染的模态框内容类型
  visible: false,
  record: null // 存储要传递给子组件的业务数据
})

2. 修改触发逻辑,仅更新数据

按钮点击时只更新state中的数据,不直接生成组件:

<Button
  onClick={() => {
    setModalConfig({
      title: 'Edit Pay Item',
      modalType: 'test',
      visible: true,
      record: record
    })
  }}
/>

3. UI层动态渲染组件

在Modal的内容渲染区域,根据state中的标识动态渲染对应组件,此时再传递setter和业务参数即可:

// 封装模态框内容渲染逻辑
const renderModalContent = () => {
  switch(modalConfig.modalType) {
    case 'test':
      // 此处传递setModalConfig完全符合规范,useState返回的setter引用稳定不会触发额外重渲染
      return <Test record={modalConfig.record} modal={setModalConfig} />
    // 其他模态框场景直接新增分支即可
    default:
      return null
  }
}

// 模态框调用处的代码示例
<Modal
  title={modalConfig.title}
  visible={modalConfig.visible}
  onCancel={() => setModalConfig(prev => ({...prev, visible: false}))}
>
  {renderModalContent()}
</Modal>

4. 可选优化:降低Modal打开时的渲染压力

  • 如果你使用的是AntD等组件库的Tabs,可以给Tabs添加destroyInactiveTabPane属性,仅渲染当前激活的Tab内容,减少Modal首次打开时的渲染量
  • 给Tab对应的5个子组件、Test组件用React.memo包裹,浅层对比props,避免props无变化时的不必要重渲染:
const Component1 = React.memo(({formProp, record}) => {
  // 原有组件逻辑
})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 04:24:03