React状态更新后无法渲染选中的新组件问题咨询
问题根因
你当前的问题核心是将React组件实例直接存储在state中,这是不符合React最佳实践的写法。React的diff算法在比对同类型组件时会默认复用现有实例,仅更新props;当你直接将<Service />实例存入state时,后续更新时React对实例引用的比对逻辑会导致它误判组件不需要更新,因此出现渲染内容不更新的问题。
你现在通过先将activeService设为空片段再赋值的方式能生效,本质是因为空片段(Fragment)和Service属于不同组件类型,diff时会先销毁旧的Service实例,再渲染新的Service实例,因此能拿到最新数据。
最佳解决方案
不要在state中存储组件实例,改为存储组件需要的原始数据,在render方法中动态渲染组件,React会自动根据数据变化更新组件:
1. 修改state定义
constructor(props) { super(props); this.state=({ services: {}, activeService: null // 仅存储service原始数据 }); }
2. 修改选中逻辑
selectedField = (field) => { const service = this.state.services[field]; if(service){ this.setState({ activeService: service }); } }
3. 动态渲染组件
render() { return( <Box sx={{ padding: 0, display: 'flex' }}> <Navigation selectFunction={this.selectedField.bind(this)}/> {this.state.activeService && <Service props={this.state.activeService} />} </Box> ); }
临时兼容方案
如果一定要保持将组件存入state的写法,可以给每个Service组件添加唯一的key属性,key发生变化时React会强制销毁旧组件、创建新的组件实例,也能解决渲染不更新的问题:
selectedField = (field) => { let service = this.state.services[field]; if(service){ // 以选中的field作为唯一key this.setState({ activeService: <Service key={field} props={service} /> }); } }
内容的提问来源于stack exchange,提问作者Kyle Batchelor
相关产品推荐
相关产品推荐

