React开发POST功能出现非受控输入转受控警告,是哪里的问题?
警告原因
你遇到的Warning: A component is changing an uncontrolled input to be controlled.警告本质是输入框的value属性从初始的undefined变为了有效值,触发了React对输入框受控/非受控状态的校验报警,代码里共有两处错误导致该问题:
- 状态初始值类型错误
你的profile状态初始值被错误定义为包含对象的数组:
后续你直接从// 错误写法,外层多了数组包裹 const [profile, setProfile] = useState([ { email: "", first_name: "", last_name: "" }, ]);profile中解构email、first_name、last_name属性,数组本身不存在这三个属性,解构结果全为undefined,输入框初始value为undefined时会被React判定为非受控组件。后续你输入内容时onChange会把profile改为普通对象,输入框value变为有效值,就触发了非受控转受控的警告。 - 提交后状态赋值错误
POST请求成功后你直接把profile赋值为数字类型的data.id:setProfile(data.id),此时profile变为数字,解构出来的三个字段再次变为undefined,会二次触发状态异常警告。
修复方案
- 修正
profile的初始值,去掉外层数组包裹 - 新增单独的状态存储返回的用户id,不要覆盖
profile的结构 - 若提交后需要清空输入框,重置
profile为初始的空值结构即可
修复后完整代码
import React, { useState } from "react"; const AddDoc = () => { // 修正初始值为普通对象 const [profile, setProfile] = useState({ email: "", first_name: "", last_name: "" }); // 新增状态存储返回的用户id const [createdUserId, setCreatedUserId] = useState(null); const { email, first_name, last_name } = profile; const postProfile = async newProfile => { const requestOptions = { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(newProfile), }; const response = await fetch("https://reqres.in/api/users", requestOptions); const data = await response.json(); // 单独存储返回的id,不覆盖profile setCreatedUserId(data.id); // 如果需要提交后清空输入框,加下面这行 // setProfile({ email: "", first_name: "", last_name: "" }); }; const onChange = change => setProfile({ ...profile, [change.target.name]: change.target.value }); const onSubmit = submit => { submit.preventDefault(); postProfile(profile); }; return ( <form className="section" onSubmit={onSubmit}> <h2>Post data</h2> {/* 提交成功后可以展示生成的id */} {createdUserId && <p>创建成功,用户ID:{createdUserId}</p>} <input type="email" name="email" value={email} onChange={onChange} placeholder="Email" /> <input type="text" name="first_name" value={first_name} onChange={onChange} placeholder="First name" /> <input type="text" name="last_name" value={last_name} onChange={onChange} placeholder="Last name" /> <button type="submit">Post</button> </form> ); }; export default AddDoc;
内容的提问来源于stack exchange,提问作者user16767975
相关产品推荐
相关产品推荐

