邂逅this.setState({ [name]: value })

1,921 阅读2分钟

最近买了本《深入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动态绑定的方法,这里就不赘述了,有兴趣的可以直接看原文

链接:medium.com/@bretdoucet…