React中GetMapping返回数据设置TextField默认值不生效问题
问题原因
defaultValue是React非受控表单组件的专属属性,仅在组件首次挂载渲染时读取一次。你的接口请求是异步逻辑,组件首次渲染时,state.info还是初始定义的空数组,此时defaultValue拿到的是undefined;等接口返回数据更新state时,组件早已完成挂载,defaultValue不会二次触发赋值。- 初始state中
info定义为空数组,从数组上读取motivoConsulta这类对象属性本身就会返回undefined,首次渲染拿不到有效值。 - 代码里同时用
info、form两个state字段存储表单数据,绑定逻辑混乱,甚至最后一个“Otras Informaciones”输入框根本没做值绑定。
修复方案
方案1:改用受控组件(官方推荐写法)
把defaultValue替换为value属性,统一将接口返回的表单数据存入form字段,所有输入框和form状态双向绑定,异步数据更新后输入框会自动同步展示最新值。
- 调整初始state,移除冗余的
info字段,统一用form存表单值:
state = { form: { motivoConsulta: "", expectativas: "", objetivosClinicos: "", otraInformacion: "", }, };
- 修改接口请求逻辑,拿到返回数据后直接更新
form状态:
getInfo = async () => { const res = await axios.get( `http://localhost:8080/expediente/findById/${this.props.id}` ); const data = res.data; this.setState({ form: { ...this.state.form, ...data } }); };
- 确保
manejadorChange方法正确更新表单状态,利用name属性匹配字段:
manejadorChange = (e) => { this.setState({ form: { ...this.state.form, [e.target.name]: e.target.value } }) }
- 替换所有TextField的绑定属性,把
defaultValue换成value,补全最后一个输入框的绑定,同时给每个输入框设置唯一id:
<TextField className="input-txt" id="motivo-consulta-input" label="Motivo de la consulta" name="motivoConsulta" onChange={this.manejadorChange} value={this.state.form.motivoConsulta} /> <TextField className="input-txt" id="expectativas-input" label="Expectativas" name="expectativas" onChange={this.manejadorChange} value={this.state.form.expectativas} /> <TextField className="input-txt" id="objetivos-clinicos-input" label="Objetivos clinicos" name="objetivosClinicos" onChange={this.manejadorChange} value={this.state.form.objetivosClinicos} /> <TextField className="input-txt" id="otra-info-input" label="Otras Informaciones" name="otraInformacion" onChange={this.manejadorChange} value={this.state.form.otraInformacion} />
方案2:保留非受控组件写法
如果一定要用defaultValue,需要等接口数据返回后再渲染表单组件,避免组件在无数据时提前挂载:
- 新增loading状态控制渲染时机:
state = { loading: true, form: { motivoConsulta: "", expectativas: "", objetivosClinicos: "", otraInformacion: "", }, };
- 接口请求完成后关闭loading状态:
getInfo = async () => { const res = await axios.get( `http://localhost:8080/expediente/findById/${this.props.id}` ); this.setState({ form: res.data, loading: false }); };
- render时增加判断,数据加载完成前不渲染表单:
render() { if (this.state.loading) return <div>数据加载中...</div> return ( {/* 原有表单结构,TextField的defaultValue统一绑定this.state.form下的对应字段 */} ) }
额外注意事项
- 不要在调用
setState后立刻打印state读取值,setState是异步执行的,立刻打印只会拿到更新前的旧值,需要读取最新值可以写在setState的第二个回调参数中:this.setState(新状态, () => console.log(this.state)) - 同页面表单元素的id必须唯一,重复id会导致label关联失效、屏幕阅读器识别错误等问题。
内容的提问来源于stack exchange,提问作者Alfred Hudson
相关产品推荐
相关产品推荐

