我试图为几个输入框编写一个事件句柄,但我意识到它无法更新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
答案 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
内的属性lastName
和list
。
因此,首先需要在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.target
和handleChange
道具,但要在您的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
}
}))
}