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

React父组件异步传值给子组件收到空对象如何解决?

问题原因

  • 子组件状态初始化时机错误:子组件Team中的name状态仅在首次渲染时从props.data.name取值,此时父组件的异步请求还未返回,teamAData/teamBData初始是空对象,因此name初始值为undefined。而useState的初始值仅会在组件首次渲染时执行一次,后续父组件更新props.data也不会同步更新子组件的name状态。
  • 父组件状态冗余:父组件同时维护了teamAData.name和单独的teamAName两个重复的队名状态,用户修改队名时仅更新了teamAName,没有同步更新teamAData,导致传递给子组件的data属性永远停留在异步请求返回的初始值。
  • 你看到的打印为空大概率是仅看到了首次渲染的打印结果:异步请求返回后父组件会触发重渲染,子组件也会跟着重渲染,此时第二次打印的props.data就会有值,你可以检查控制台是否有两次打印输出。
  • 额外bug:父组件第一行const [id, setId] = props.match.params.id;写法错误,useState返回值是数组,需要改为const [id, setId] = useState(props.match.params.id);

解决方法

方案1:简化状态,去掉冗余(推荐)

父组件删掉单独的teamAName、teamBName状态,队名统一从teamAData/teamBData中取值,修改handleNameChange逻辑同步更新teamAData:

// 父组件删除这两行
// const [teamAName, setTeamAName] = useState('');
// const [teamBName, setTeamBName] = useState('');

// 修改handleNameChange
function handleNameChange(teamId, name) {
    if (teamId == 'A')
        setTeamAData(prev => ({...prev, name}));
    else
        setTeamBData(prev => ({...prev, name}));
}

子组件不单独维护name本地状态,直接使用props.data.name:

// 子组件删除这行
// const [name, setName] = useState(props.data.name);

// 修改input和handleNameChange
function handleNameChange(event) {
    event.preventDefault();
    props.onNameChange(props.id, event.target.value);
}

<input 
    type="text" 
    value={props.data.name || ''} 
    onChange={handleNameChange} 
    className="input" 
    placeholder={placeholderName}
/>

方案2:子组件监听props变化同步本地状态

如果需要保留子组件的本地name状态,新增useEffect监听props.data变化,主动更新本地状态:

// 子组件新增useEffect
useEffect(() => {
    setName(props.data.name || '')
}, [props.data])

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 20:45:03