React中父组件state数据无法设置到子组件state的问题
问题根因
出现这个现象的核心原因是React类组件的生命周期执行时机问题:
componentDidMount仅会在组件首次挂载完成后触发1次。子组件第一次挂载时,父组件的接口请求还未返回,传入的data是初始值空数组,子组件就在这一次componentDidMount执行时把空数组赋值给了本地items状态。- 后续父组件接口请求完成,通过
setState更新了传入子组件的props,子组件会触发重新渲染,所以你在render里打印this.props.data能拿到最新的数组,但componentDidMount不会在props更新时重复执行,没有任何逻辑把新的props值同步到本地state,所以state里的items一直停留在首次赋值的空数组。
额外提一句你贴的父组件代码里有个笔误:render方法中写的是const data = this.state,这会把整个父组件state对象(结构为{data: 数组})传给子组件,如果你本地控制台打印props拿到的是纯数值数组,说明你实际运行的代码已经正确做了解构,忽略这条即可。
修复方案
优先推荐:直接使用props渲染,无需复制到本地state
90%以上的场景下都不需要把父组件传入的props额外存一份到子组件本地state,直接读取props渲染即可,从根源上避免props和本地state不同步的问题,代码也更简洁:
// 修正后的子组件 class Child extends Component { render() { // 直接从props取数据,移除不必要的本地items状态 const { data } = this.props; console.log("子组件渲染数据:", data); return ( <> <ReactApexChart options={data} /> </> ); } } // 父组件render部分修正传值(如果之前没写解构的话) render() { const { data } = this.state; return ( <> <Child data={data} /> </> ); }
特殊场景:必须存本地state做二次处理时,用静态生命周期同步props
如果业务上确实需要把props存在本地state做加工转换,不要在componentDidMount里一次性赋值,要通过getDerivedStateFromProps静态生命周期监听props变化,同步更新本地state:
class Child extends Component { constructor(props) { super(props); this.state = { items: [], }; } // 每次组件接收到新props、触发更新前都会执行 static getDerivedStateFromProps(nextProps, prevState) { // 增加判断,仅当传入的data变化时才更新本地state,避免不必要的重渲染 if (nextProps.data !== prevState.items) { return { items: nextProps.data } } // 不需要更新state时返回null return null; } render() { const { items } = this.state; console.log("Child data from state: ", items); return ( <> <ReactApexChart options={items} /> </> ); } }
注意:不要使用已被React标记为不安全的废弃生命周期
componentWillReceiveProps来做状态同步。
内容的提问来源于stack exchange,提问作者Fabian
相关产品推荐
相关产品推荐

