页面渲染时如何让下拉框选中已保存值?React代码求助
嘿,我来帮你捋捋这个问题~
首先回答你最关心的:select完全是这个场景的最佳选择。因为你的可联系时段是预设的固定选项(从this.state.times来的),用select能确保用户只能选择规范的时间格式,避免手动输入带来的格式混乱、数据库存储不一致的问题,完全没必要换其他组件。
你不用在页面加载时调用onChange方法来设置选中值——React的表单控件是受控组件,只要给select绑定value属性,对应到你的state变量,就能自动选中对应的值,这才是正确的姿势。
先看你的代码里几个需要修正的地方,然后给你调整后的完整代码:
1. 构造函数的语法错误
你把if(this.props.employeeKey)直接写在了class顶层,这是不合法的,应该把判断逻辑放到constructor内部。而且初始化TimeFrom和TimeTo的时候,直接从AvailTimes里取对应值就行,不用留空。
2. setState的语法错误
你写的this.setState(Phone: e.target.value)是错的,setState需要接收一个对象,应该是this.setState({ Phone: e.target.value }),每个case都要修正。
3. 给select添加value属性
给两个select分别绑定value={this.state.TimeFrom}和value={this.state.TimeTo},这样组件渲染时就会自动选中你从数据库拿到的时间值。
4. 优化事件绑定&其他细节
建议在constructor里提前绑定onChange方法,避免每次render都创建新的绑定函数;另外React组件只能返回单个根元素,需要把两个label用容器包裹;列表渲染的option要加key属性,避免React警告。
修正后的完整代码
export default class Employee extends Component { constructor(props) { super(props); // 根据props初始化state if (this.props.employeeKey) { const availTimes = JSON.parse(this.props.availTimes); this.state = { Name: this.props.name, Phone: this.props.phone, SecondaryPhone: this.props.secondaryPhone, AvailTimes: availTimes, times: this.props.times, TimeFrom: availTimes.From, // 直接赋值数据库返回的From时间 TimeTo: availTimes.To // 直接赋值数据库返回的To时间 }; } else { this.state = { Name: "", Phone: "", SecondaryPhone: "", AvailTimes: "", times: [], TimeFrom: "", TimeTo: "" }; } // 提前绑定onChange方法,优化性能 this.onChange = this.onChange.bind(this); } onChange(value, e) { switch(value) { case "Phone": this.setState({ Phone: e.target.value }); break; case "Name": this.setState({ Name: e.target.value }); break; case "SecondaryPhone": this.setState({ SecondaryPhone: e.target.value }); break; case "FromTime": this.setState({ TimeFrom: e.target.value }); break; case "ToTime": this.setState({ TimeTo: e.target.value }); break; default: break; } } render() { return ( <div> {/* 用div包裹成单个根元素 */} <label> From: <select value={this.state.TimeFrom} // 绑定value实现自动选中 onChange={(e) => this.onChange('FromTime', e)} > {this.state.times.map(time => ( <option key={time} value={time}> {time} </option> {/* 必须加key属性 */} ))} </select> </label> <label> To: <select value={this.state.TimeTo} // 绑定value实现自动选中 onChange={(e) => this.onChange('ToTime', e)} > {this.state.times.map(time => ( <option key={time} value={time}> {time} </option> ))} </select> </label> </div> ); } }
补充说明
为什么不用调用onChange?因为当组件初始化时,我们已经把数据库里的时间值赋值给了TimeFrom和TimeTo,然后通过value属性绑定到select上,React会自动让select选中对应value的option——这就是受控组件的核心逻辑,完全不需要额外调用onChange来触发选中,那样反而会多一次不必要的state更新。
内容的提问来源于stack exchange,提问作者Michael

