我对JS很新,我在理解如何正确实现在React中传递给setState的回调时遇到了一些控制输入。以下代码是我到目前为止的代码:
class App extends React.Component {
...
this.state = {
properties: {
width: '',
height: ''
}
this.handleChange = this.handleChange.bind(this); //edit 1
}
handleChange(e){
this.setState(() => ({ properties[e.target.name]: e.target.value })) //edit 2
}
render(){
return(
<input
type="text"
value={this.state.properties.width}
name="width"
onChange={this.handleChange} />
...
)
}
}
您需要更改handleChange
声明:
class App extends React.Component {
...
handleChange = (e) => {
this.setState({ properties[e.target.name]: e.target.value })
}
...
}
当你写handleChange = (e) => {...}
它会将函数的this
指针绑定到您的组件,以便您可以访问setState
正如@ Li357指出的那样,它根本不会绑定,相反它会创建一个类的属性,它是一个不绑定this
的箭头函数,捕获周围范围的this
值,即类。
更新:
已经指出使用箭头函数作为类属性是一个实验特征,因此在组件的this.handleChange = this.handleChange.bind(this)
中使用constructor
更安全。我得到了使用此代码的示例:
handleChange(event) {
const target = event.target;
this.setState((prevState) => ({
properties: {...prevState.properties, ...{ [target.name]: target.value } }
})
);
}
我不完全确定它为什么会这样做,我猜它与setState
是异步的事实有关,而react
在自己的SyntheticEvent
(参见will be reused and all properties will be nullified after the event callback has been invoked
)中包装事件。因此,如果您将react docs之外的原始引用存储到target
,它将在setState
中得到范围并使用。
这是一个关于setState
的工作示例。
更新2:
根据codesandbox,无法以异步方式访问反应react docs。解决这个问题的一种方法是调用SyntheticEvent
来删除包装器,但这可能不是一个好主意,因为event.persist()
是浏览器本机事件的跨浏览器包装器,可确保事件在所有浏览器中的工作方式相同。