React Hooks 如何在调用setState时将其自身作为prop传递避免卡顿
卡顿根因
你的卡顿问题和传递setState本身无关,核心问题是你直接把React组件实例(
)存入了state中,这是React官方不推荐的写法:state仅应该存储可序列化的状态数据,存组件实例会导致React在状态更新时额外处理不必要的组件引用逻辑、重复创建组件实例,拉长渲染链路,最终出现卡顿。return (<Test />)
其次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
相关产品推荐
相关产品推荐

