You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

useEffect更新父组件状态后子组件props状态读取异常排查

异常原因

这是React useState钩子的标准运行机制导致的,不属于框架bug:

  • useState接收的初始值参数仅在组件首次挂载的第一次渲染时生效,后续组件因props变更、父组件重渲染触发更新时,React会直接保留该state已存储的值,完全忽略传入的初始参数,不会自动将props的更新同步到组件本地state中。
  • Second组件没有维护独立的本地状态,每次渲染都直接读取当前最新的props值,因此父组件通过setSomeVar更新状态后,Second能立刻拿到新的数组['a','b','c']完成渲染。
  • First组件首次挂载时,用当时props携带的初始值['a']完成了本地stateletters的初始化,后续父组件props更新触发First重渲染时,useState(props.letters.dos)这行代码不会再把新传入的props值写入本地state,组件始终读取首次初始化的本地state值,因此只渲染初始的a,看不到后续追加的b、c。
相关代码

App.js

import './App.css';
import First from './First';
import Second from './Second';
import { useEffect, useState } from 'react';

function App() {
  const [someVar, setSomeVar] = useState({dos:['a']});

  useEffect(()=>{
    console.log('useEffect')
    setSomeVar({dos:['a', 'b', 'c']})
  }, [])

  return (
    <div className="App">
      <header className="App-header">
        <First letters={someVar}></First>
        <hr/>
        <Second letters={someVar}></Second>
      </header>
    </div>
  );
}

export default App;

First.js

import { useState } from "react";

export default function First(props) {
  const [letters, setLetter] = useState(props.letters.dos);

  return (
    <div>
      {letters.map((letter) => {
        return <span key={letter}>{letter}</span>;
      })}
    </div>
  );
}

Second.js

export default function Second(props) {

  return (
    <div>
      {props.letters.dos.map((letter) => {
        return <span key={letter}>{letter}</span>;
      })}
    </div>
  );
}
渲染效果

效果截图

内容的提问来源于stack exchange,提问作者mjsr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.03 07:15:53