ReactJS事件处理程序更新字典值的状态

时间:2019-01-27 07:11:20

标签: reactjs

我试图为几个输入框编写一个事件句柄,但我意识到它无法更新dict的状态。如果我将其更改为字符串,则效果很好。

如果我将状态更改为“跟随”,则效果很好。

this.state = {          
        firstName: "",
        lastName: ""    
}

但是没有遵循

import React, {Component} from "react"

class App extends Component {
    constructor() {
        super()
        this.state = {
            list: {
                firstName: "",
                lastName: ""    
            }

        }
        this.handleChange = this.handleChange.bind(this)
    }

    handleChange(event) {
        const {name, value} = event.target
        console.log(name)
        this.setState({
            [name]: value
        })
    }

    render() {
        return (
            <form>
                <input 
                    type="text" 
                    value={this.state.firstName} 
                    name="list[firstName]" 
                    placeholder="First Name" 
                    onChange={this.handleChange} 
                />
                <br />
                <input 
                    type="text" 
                    value={this.state.lastName} 
                    name="list[lastName]" 
                    placeholder="Last Name" 
                    onChange={this.handleChange} 
                />

                <h1>{this.state.firstName} {this.state.lastName}</h1>
            </form>
        )
    }
}

export default App

3 个答案:

答案 0 :(得分:1)

在您的handleChange函数中,您可以将setState更改为以下内容:

this.setState({
      list: {
        [name]: value
      }
    })
// in input
value={this.state.list.firstName} 

答案 1 :(得分:1)

第二种情况不起作用,因为存在缺陷。因此,要使代码运行,您需要在输入字段中进行两次更改

1)name="list[firstName]"name="firstName"

2)value={this.state.firstName}value={this.state.list.firstName}

如果您在输入字段中使用name="list[firstName]",则只要执行[name]: value中的handleChange方法,它的计算结果为['list[firstName]']: value,它将创建另一个属性list[firstName]在该州。

state = { list: {...}, list[firstName]: value }

因此,它不会像您期望的那样更新firstName中的属性list

详细信息: Computed Property Names

使用value={this.state.list.firstName},我们可以将状态list.firstName与输入字段进行映射

    <input 
            type="text" 
            // do not use value={this.state.firstName} 
            value={this.state.list.firstName} 
            // do not use name="list[firstName]"
            name="firstName" 
            placeholder="First Name" 
            onChange={this.handleChange} 
    />

    <input 
            type="text" 
            value={this.state.list.lastName} 
            name="lastName" 
            placeholder="Last Name" 
            onChange={this.handleChange} 
    />

在您的handleChange方法中,您尝试更新firstName内的属性lastNamelist

因此,首先需要在list方法内将this.setState用作this.setState({ list: {...}})

由于list是一个对象,您想更新list的特定属性,因此首先需要使用传播运算符复制list内部的所有属性。然后,您可以使用动态/计算属性来更改要更改的属性。因此,将您的handleChange方法更改为

handleChange(event) {
        const {name, value} = event.target
        this.setState({
            list: {
              // copy all properties inside the "list" 
              // so that we change only the property 
              // we need to change and keep other properties as it is
              ...this.state.list,
              // dynamically changing property
              [name]: value
            }
        })
    }

答案 2 :(得分:1)

首先,您正在name函数中正确地从value破坏event.targethandleChange道具,但要在您的name属性上进行设置两个<input>元素不直观。您的name属性目前是"list[firstName]""list[lastName]"->这不会像您希望的那样进入您的this.state.list[firstName] / this.state.list[lastName]属性-相反,您应该更改您的name属性以反映您的state值,例如:

<input
    name="firstName"
    {/* other props stay the same... */}
/>
<input
    name="lastName"
    {/* other props stay the same... */}
/>

现在,您的<input>元素具有name属性,它们也与state上的值匹配,因此您可以将handleChange函数更改为以下内容:

handleChange(event) {
    // get name and value properties from event target
    const {name, value} = event.target
    this.setState(prevState => ({
        // update your 'list' property
        list: {
          // spread old values into this object so you don't lose any data
          ...prevState.list,
          // update this field's value
          [name]: value
        }
    }))
}