React.js使用react-awesome-tabs切换标签时如何阻止重渲染保留输入内容
问题根因
- 当前代码逻辑下所有
<Tab>组件都渲染同一个状态this.state.activePage,切换标签时该状态会被新页面覆盖,旧标签的内容和内部状态自然丢失。 - 使用
index作为Tab的key属性,当标签新增、删除、顺序变化时,React会错误复用组件实例,也会触发状态重置。
解决方案
步骤1:调整标签存储结构
将每个标签对应的页面实例独立存储,不要共用同一个activePage状态,把tabs数组存入state,每个项包含唯一标识、标题、对应页面组件三个字段:
// state初始化示例 state = { activeTab: 0, tabs: [ // 初始标签示例 { id: 'tab-home', title: '首页', page: <HomePage /> } ], // 其余原有状态保留 }
步骤2:修改新增标签逻辑
侧边栏点击新增标签时,直接往state的tabs数组推入新的标签项,不要修改全局的activePage:
// 侧边菜单点击事件示例 handleSideMenuClick = (menuItem) => { const newTab = { // 生成唯一ID,禁止用index当标识 id: `tab-${Date.now()}-${menuItem.key}`, title: menuItem.label, page: menuItem.component } this.setState(prev => ({ tabs: [...prev.tabs, newTab], // 新增后自动激活新标签 activeTab: prev.tabs.length })) }
步骤3:重写Tabs渲染逻辑
每个Tab渲染自身对应的页面组件,用唯一id作为key:
<Tabs active={this.state.activeTab} onTabSwitch={this.handleTabSwitch.bind(this)} onTabClose={this.handleTabClose.bind(this)} onTabAdd={this.handleTabAdd.bind(this)} draggable={true} showAdd={true} > { this.state.tabs.map((tab, index) => { return ( <Tab key={tab.id} title={tab.title} showClose={true} > {tab.page} </Tab> ) }) } </Tabs>
步骤4:优化重渲染(可选)
如果要进一步避免不必要的重渲染,给你的页面组件做一层优化:
- 函数组件包裹
React.memo - 类组件改为继承
React.PureComponent
只要组件的props没有发生变化,就不会触发重渲染,内部的表单输入状态会完全保留。
注意事项
关闭标签时,只需删除state.tabs数组中对应id的项即可,不要修改其他标签的page属性,避免状态被意外重置。
内容的提问来源于stack exchange,提问作者Veysel Turan
相关产品推荐
相关产品推荐

