如何在React中存储单选框值?遇取值与状态循环问题求解
问题:React中无法获取单选框选中值并存储
我需要实现用户输入内容的展示功能,提交新输入时渲染出来,但目前没法存储单选框的选择值,试过bind(this)等方法都无效。尝试给每个单选框或外层div加onChange事件也获取不到值,设置checked属性时程序还会陷入循环。
以下是我的代码:
import React, { Component } from "react"; class Input extends Component { state = { nameItems: [], ageItems: [], statusItems: [], nameInput: '', ageInput: '', statusInput: '' } nameChangeHandler = ({target:{value}}) => this.setState({ nameInput: value }) ageChangeHandler = ({target:{value}}) => this.setState({ ageInput: value }) submitHandler = e =>{ e.preventDefault() this.setState({ nameItems: [...this.state.nameItems, this.state.nameInput], ageItems: [...this.state.ageItems, this.state.ageInput], statusItems: [...this.state.statusItems, this.state.statusInput], nameInput: '', ageInput: '', statusInput: '' }) } render() { return ( <div> <h1>User signup form</h1> <form onSubmit={this.submitHandler}> <label for="name">Name:</label><br /> <input type="text" id="name" name="name" value={this.state.nameInput} onChange={this.nameChangeHandler} /><br /> <label for="age">Age:</label><br /> <input type="number" id="age" name="age" value={this.state.ageInput} onChange={this.ageChangeHandler}/><br /> <div class="schoolYear"> <p>Your status:</p> <input type="radio" id="freshman" name="status" value="freshman" /> <label for="freshman">Freshman</label><br /> <input type="radio" id="css" name="status" value="sophomore" /> <label for="sophomore">Sophomore</label><br /> <input type="radio" id="junior" name="status" value="junior" /> <label for="junior">Junior</label><br /> <input type="radio" id="senior" name="status" value="senior" /> <label for="senior">Senior</label><br /> </div> <input class="submit" type="submit" value="Submit" /> <ul> { this.state.nameItems.map((key) => <li>{key}</li>) } { this.state.ageItems.map((key) => <li>{key}</li>) } { this.state.statusItems.map((key) => <li>{key}</li>) } </ul> </form> </div> ) } } export default Input;
解决方案
1. 新增单选框的change处理函数
给所有单选框绑定同一个statusChangeHandler,用来获取选中值并更新state:
statusChangeHandler = ({ target: { value } }) => { this.setState({ statusInput: value }); };
2. 修复单选框的受控状态
给每个单选框添加checked属性,绑定this.state.statusInput === 当前单选框的value,这样既可以控制选中状态,也不会触发循环(因为只有当选中值和state匹配时才会标记checked)。同时修正之前的id错误(比如第二个单选框id是css对应label的sophomore,改成sophomore)。
3. 统一绑定onChange事件
给每个单选框加上onChange={this.statusChangeHandler}。
修改后的完整代码
import React, { Component } from "react"; class Input extends Component { state = { nameItems: [], ageItems: [], statusItems: [], nameInput: '', ageInput: '', statusInput: '' } nameChangeHandler = ({ target: { value } }) => this.setState({ nameInput: value }) ageChangeHandler = ({ target: { value } }) => this.setState({ ageInput: value }) // 新增单选框处理函数 statusChangeHandler = ({ target: { value } }) => { this.setState({ statusInput: value }); }; submitHandler = e => { e.preventDefault() this.setState({ nameItems: [...this.state.nameItems, this.state.nameInput], ageItems: [...this.state.ageItems, this.state.ageInput], statusItems: [...this.state.statusItems, this.state.statusInput], nameInput: '', ageInput: '', statusInput: '' }) } render() { return ( <div> <h1>User signup form</h1> <form onSubmit={this.submitHandler}> <label htmlFor="name">Name:</label><br /> <input type="text" id="name" name="name" value={this.state.nameInput} onChange={this.nameChangeHandler} /><br /> <label htmlFor="age">Age:</label><br /> <input type="number" id="age" name="age" value={this.state.ageInput} onChange={this.ageChangeHandler} /><br /> <div className="schoolYear"> <p>Your status:</p> <input type="radio" id="freshman" name="status" value="freshman" checked={this.state.statusInput === 'freshman'} onChange={this.statusChangeHandler} /> <label htmlFor="freshman">Freshman</label><br /> <input type="radio" id="sophomore" // 修正id错误 name="status" value="sophomore" checked={this.state.statusInput === 'sophomore'} onChange={this.statusChangeHandler} /> <label htmlFor="sophomore">Sophomore</label><br /> <input type="radio" id="junior" name="status" value="junior" checked={this.state.statusInput === 'junior'} onChange={this.statusChangeHandler} /> <label htmlFor="junior">Junior</label><br /> <input type="radio" id="senior" name="status" value="senior" checked={this.state.statusInput === 'senior'} onChange={this.statusChangeHandler} /> <label htmlFor="senior">Senior</label><br /> </div> <input className="submit" type="submit" value="Submit" /> <ul> {this.state.nameItems.map((item, index) => <li key={index}>Name: {item}</li>)} {this.state.ageItems.map((item, index) => <li key={index}>Age: {item}</li>)} {this.state.statusItems.map((item, index) => <li key={index}>Status: {item}</li>)} </ul> </form> </div> ) } } export default Input;
额外优化:给map渲染的列表项加上key属性(用index作为临时key,实际项目推荐用唯一id),同时修改class为className(React中DOM元素的类名用className),for为htmlFor(避免和JS的for循环关键字冲突)。
内容的提问来源于stack exchange,提问作者Lingdu
相关产品推荐
相关产品推荐

