React嵌套组件无法获取axios返回数据值的问题
问题诊断与解决方案
核心原因
你的EditableText组件大概率只在首次挂载时读取initialValue,没有监听后续的props更新。当父组件的userInfo从null加载完成变为真实数据后,虽然initialValue已经更新,但EditableText内部的状态没有同步,所以一直停留在初始的"Loading..."状态。
另外注意你代码里的一个笔误:第一个EditableText(id="age")的initialValue写成了userInfo.weight,应该是userInfo.age,这个也会导致年龄字段显示错误数据。
解决方案一:修改EditableText组件(推荐)
如果能修改EditableText的源码,添加对initialValue的监听,确保内部状态和props同步:
import { useState, useEffect } from 'react'; const EditableText = ({ initialValue, label, id, ...rest }) => { const [currentValue, setCurrentValue] = useState(initialValue); // 监听initialValue变化,实时更新内部状态 useEffect(() => { setCurrentValue(initialValue); }, [initialValue]); // 组件的其他逻辑(比如编辑状态切换、输入处理等) return ( <div> <label htmlFor={id}>{label}</label> {/* 渲染时使用currentValue */} {rest.type === 'select' ? ( <select id={id} value={currentValue} onChange={(e) => setCurrentValue(e.target.value)} > {rest.options.map(opt => ( <option key={opt} value={opt}>{opt}</option> ))} </select> ) : ( <input id={id} type={rest.type} value={currentValue} onChange={(e) => setCurrentValue(e.target.value)} placeholder={rest.placeholder} /> )} </div> ); };
解决方案二:延迟渲染EditableText(无需修改组件)
如果无法修改EditableText组件,就等到userInfo加载完成后再渲染这些组件,确保initialValue一开始就传入真实数据:
// 在return的JSX中替换原有的EditableText部分 {userInfo ? ( <div style={{display: 'flex', gap: '1rem'}}> <EditableText id="age" label="Age" placeholder="Age" type="number" initialValue={userInfo.age} style={{flex: 1}} /> <EditableText id="weight" label="Weight" placeholder="Weight" type="number" initialValue={userInfo.weight} style={{flex: 1}} /> <EditableText id="height" label="Height" placeholder="Height" type="number" initialValue={userInfo.height} style={{flex: 1}} /> <EditableText id="callisthenics" label="Callisthenics" type="select" options={['Beginner', 'Intermediate', 'Advanced']} initialValue={userInfo.experience} style={{flex: 1}} /> </div> ) : ( // 加载状态的占位符,和EditableText布局保持一致 <div style={{display: 'flex', gap: '1rem'}}> <div style={{flex:1, padding: '0.5rem', border: '1px solid #eee'}}>Loading...</div> <div style={{flex:1, padding: '0.5rem', border: '1px solid #eee'}}>Loading...</div> <div style={{flex:1, padding: '0.5rem', border: '1px solid #eee'}}>Loading...</div> <div style={{flex:1, padding: '0.5rem', border: '1px solid #eee'}}>Loading...</div> </div> )}
内容的提问来源于stack exchange,提问作者user21736604
相关产品推荐
相关产品推荐

