React函数组件中表单Radio button触发控制台警告的原因与解决
React单选按钮控制台警告问题解答
问题描述
在React项目中收集表单输入并传递到下一页,添加Radio button后功能正常,但Chrome控制台出现如下警告:
Warning: You provided a
checkedprop to a form field without anonChangehandler. This will render a read-only field. If the field should be mutable usedefaultChecked. Otherwise, set eitheronChangeorreadOnly.
相关代码如下:
import {useLocation} from 'react-router-dom'; import { useState } from "react"; import { useNavigate } from "react-router-dom"; const Second = () => { const navigate = useNavigate(); const location = useLocation(); const contact=location.state; const [name, setName] = useState(""); const [wording, setWording] = useState(""); const handleSecSubmit = (e) => { e.preventDefault(); const contacttotal={ ...contact, ...{name}, ...{wording} }; console.log(contacttotal); navigate("/final", { state: { contacttotal } }); } return ( <div className="Second"> <h1>This is Second Input Page</h1> <form autoComplete="on" onSubmit={handleSecSubmit}> <dd>Name</dd> <input type="text" value={name} onChange={(e) => setName(e.target.value) } required ></input> <dd>Wording</dd> <div> <div onChange={(e) => setWording(e.target.value)}> <label><input type="radio" value='United States' name="wording" checked={wording === "United States"} />United States</label> <label><input type="radio" value='British' name="wording" checked={wording === "British"} />British</label> </div> </div> <br/> <button>submit</button> </form> </div> ); } export default Second;
警告含义
这个警告的核心逻辑是:你给表单字段(此处为每个单选按钮)设置了checked属性(用于受控组件绑定状态),但没有给该字段本身绑定onChange事件处理函数。React会判定这个字段为只读状态,因为它无法响应用户的点击操作来同步更新状态。
如果字段需要允许用户修改,有两种合规选择:
- 用
defaultChecked替代checked,将组件改为非受控组件; - 给每个字段添加
onChange处理函数,保持受控组件的状态同步逻辑; - 若字段确实为只读,显式设置
readOnly属性。
解决方法
你的代码中把onChange绑定在了父级<div>上,虽然功能上能触发状态更新,但React的检查机制是针对单个表单元素的——每个设置了checked的单选按钮都需要绑定自己的onChange处理函数。
修改方案很简单,将onChange事件移到每个单选按钮上即可:
import {useLocation} from 'react-router-dom'; import { useState } from "react"; import { useNavigate } from "react-router-dom"; const Second = () => { const navigate = useNavigate(); const location = useLocation(); const contact=location.state; const [name, setName] = useState(""); const [wording, setWording] = useState(""); const handleSecSubmit = (e) => { e.preventDefault(); const contacttotal={ ...contact, ...{name}, ...{wording} }; console.log(contacttotal); navigate("/final", { state: { contacttotal } }); } // 抽离单独的处理函数,让代码更简洁 const handleWordingChange = (e) => { setWording(e.target.value); } return ( <div className="Second"> <h1>This is Second Input Page</h1> <form autoComplete="on" onSubmit={handleSecSubmit}> <dd>Name</dd> <input type="text" value={name} onChange={(e) => setName(e.target.value)} required ></input> <dd>Wording</dd> <div> <div> <label><input type="radio" value='United States' name="wording" checked={wording === "United States"} onChange={handleWordingChange} />United States</label> <label><input type="radio" value='British' name="wording" checked={wording === "British"} onChange={handleWordingChange} />British</label> </div> </div> <br/> <button>submit</button> </form> </div> ); } export default Second;
修改后,每个单选按钮都拥有了自己的onChange处理函数,React不会再抛出警告,同时受控组件的状态同步逻辑也能正常运行。
内容的提问来源于stack exchange,提问作者FormosaMephitis
相关产品推荐
相关产品推荐

