最近买了本《深入React技术栈》在啃,看到受控组件和非受控组件那节时被一段代码给“震精”了
import React, {Component} from 'React'
class FormApp extends Component {
constructor(props)
super(props)
this.state = {
name: '',
age: 18
}
handleChange(name, e){
const {value} = e.target
this.setState({
[name]: value
})
}
render(){
const {name, age} = this.state
return(
<div>
<input value={name} onChange={this.handleChange.bind(this, 'name')}/>
<input value={age} onChange={this.handleChange.bind(this, 'age')}/>
</div>
)
}
}因为对
this.setState({
[name]: value
})感到陌生
两个受控组件input都是调用的同一个事件handleChange,并且事件接收两个参数——name和event,通过name判断组件是name的input还是age的input,然后再用注册的event获取当前的输入分别赋值给name和age从而改变state。这让我联想到了ES6里的解构赋值,但是在React里,定义一个state是key-object的形式,改变state是改变key所对应的object的值。
上面代码里定义了state有两个key——name和age,但是在setState里又是怎么做到可以分别修改两个key所对应的值呢?
谷歌到Medium的一篇文章解开了我的疑惑
原文中有一句话:

大概意思是:
在Javascript中,当创建对象并将该对象的键包装在数组括号[]中时,您可以动态设置该键。
举个现实中开发经常遇到的列子
当我们用React写一个表单组件时,这个表单组件包含了一系列的输入控件,像是姓名、年龄、性别、爱好等等,对每一个输入框(这里都指的是受控组件)都有一个handleChange方法来处理用户输入,类似于handleNameChange、handleAgeChange、handleGenderChange等,有多少个受控组件就要写多少个这样的绑定方法,难免会导致代码冗余和逻辑混乱,所以这个时候运用JS动态分配对象key的方式可以轻松解决这类问题。
对于每一个输入组件,我们都可以给它加个name属性,值就是这个输入框要输入的类型,比如姓名输入框就是
<input value{this.state.name} onChange={this.handleChange} name='name'/>年龄输入框
<input value={this.state.age} onChange={this.handleChage} name='age'/>然后每个输入框只需要绑定一个handleChange方法就可以了,再通过
handleChange = (event) => {
const {value, name} = event.target
this.setState({
[name]: value
})
}改变对应组件的state
此外文中还给出了用模板语法实现对象key动态绑定的方法,这里就不赘述了,有兴趣的可以直接看原文