React.js切换激活Tab时如何避免子组件内的state数据被清空?
问题根因
- 你的代码存在低级错误:
Simple组件中,constructor 里已经给this.tabs赋值了标签页配置,后面额外加的tabs = []行直接覆盖了这个配置,先删除这行冗余代码。 - 核心原因:你使用的
react-awesome-tabs库默认仅渲染当前活跃的标签页,切换标签时非活跃的子组件会被直接卸载,组件卸载后内部的 state 会被销毁,切回标签时组件重新挂载,state 自然回到初始空值。
注意:你理解的「阻止子组件二次渲染」是误区,普通的组件重渲染不会清空 state,只有卸载后重新挂载才会丢失 state,所以核心要解决的是避免切换标签时子组件被卸载。
解决方案(按推荐优先级排序)
方案1:非活跃标签仅隐藏不卸载(改造成本最低)
不需要修改子组件代码,只需要调整标签内容的渲染逻辑,所有标签内容都提前渲染,非活跃的通过样式隐藏:
// Simple组件render函数修改 render() { return ( <div className="App" style={{/* 你的原有样式 */}}> <Tabs active={this.state.activeTab} onTabSwitch={this.handleTabSwitch.bind(this)} draggable={true} showAdd={true} > { this.tabs.map((value, index) => { return ( <Tab key={index} title={value.title} showClose={true} > {/* 非活跃标签加display:none隐藏,不卸载 */} <div style={{display: this.state.activeTab === index ? 'block' : 'none'}}> {value.content} </div> </Tab> ); }) } </Tabs> </div> ); }
如果react-awesome-tabs本身会自动移除非活跃Tab的内容,你可以把标签内容移到Tabs组件外单独渲染,只保留Tabs组件作为标签切换头使用即可。
方案2:状态提升(最稳定,适合后续要提交表单的场景)
你有35-40个输入项的情况下,把所有表单状态提到父组件Simple中管理,子组件只通过props接收值和修改回调,就算子组件被卸载,数据也会保存在父组件中:
// 父组件state修改 this.state = { activeTab: 0, firstTabData: {name: ''}, // 存FirstTab的所有表单数据 secondTabData: {surName: ''} // 存SecondTab的所有表单数据 }; // 父组件给子组件传props this.tabs = [ { title: 'Tab1', content: <FirstTab data={this.state.firstTabData} onChange={(newData) => { this.setState({firstTabData: {...this.state.firstTabData, ...newData}}) }} /> }, { title: 'Tab2', content: <SecondTab data={this.state.secondTabData} onChange={(newData) => { this.setState({secondTabData: {...this.state.secondTabData, ...newData}}) }} /> }, ];
// FirstTab组件修改,不用自己存state class FirstTab extends Component { ChangeName(e){ this.props.onChange({name: e.target.value}) } render() { // 原有样式不变 return ( <div > <div style={divStyle}> <label style={labelStyle} htmlFor='uyeNo' >Name: </label> <input style={inputStyle} onBlur={(e)=>{this.ChangeName(e)}} type='text' /> <textarea style={textareaStyle} value={this.props.data.name} /> <br></br> </div> </div> ); } }
方案3:使用缓存组件
如果不想改现有逻辑,可以用社区的react-activation库实现类似Vue的keep-alive能力,缓存组件实例,切换标签时不会卸载组件,state自然不会丢失。
内容的提问来源于stack exchange,提问作者Ali
相关产品推荐
相关产品推荐

