React开发遇文本输入框从非受控转受控警告如何解决?
警告产生原因
- React 对输入组件的受控/非受控状态判定逻辑为:只要
value属性绑定的值为undefined或null,就会被识别为非受控组件;如果value绑定了明确的非空(指非undefined/null)值,且有配套的onChange事件更新绑定值,就识别为受控组件。 - 你的组件初始化时,
username和email的state没有设置初始值,默认值为undefined,此时输入框被识别为非受控组件;当你在输入框输入内容触发onChange后,state被更新为字符串类型的有效值,输入框切换为受控组件,两种状态切换就触发了该警告。
代码错误点
useState初始化时未传入初始值,导致绑定到输入框value的初始值为undefined,触发状态切换。
// 错误写法 const [username, setUsername] = useState(); const [email, setEmail] = useState();
额外可优化点:原代码中Username对应的label标签htmlFor属性值为firstName,和输入框的id="username"不匹配,点击label无法正常聚焦到对应输入框。
解决方法
如果你要使用官方推荐的受控组件表单处理方案,只需要给state传入初始空字符串即可,修改后不会再出现状态切换警告。
// 修正后写法 const [username, setUsername] = useState(''); const [email, setEmail] = useState('');
如果需要使用非受控组件的写法,就删除输入框上的value属性,改用defaultValue传初始值,提交时通过表单实例或者ref获取输入值即可,示例如下:
<input type="text" name="username" id="username" defaultValue="" />
修正后完整代码
import React, { useState } from "react"; const ControlledInputs = () => { // 新增初始空字符串 const [username, setUsername] = useState(''); const [email, setEmail] = useState(''); const handleSubmit = (e) => { e.preventDefault(); console.log(username, email); }; return ( <> <article> <form className="form" onSubmit={handleSubmit}> <div className="form-control"> <!-- 修正htmlFor属性值 --> <label htmlFor="username">Username :</label> <input type="text" name="username" id="username" value={username} onChange={(e) => setUsername(e.target.value)} /> </div> <div className="form-control"> <label htmlFor="email">Email : </label> <input type="text" name="email" id="email" value={email} onChange={(e) => setEmail(e.target.value)} /> </div> <button type="submit">Add User</button> </form> </article> </> ); }; export default ControlledInputs;
内容的提问来源于stack exchange,提问作者user13599891
相关产品推荐
相关产品推荐

