嵌套状态对象中的回调 [英] callback in nested state object
问题描述
我对 JS 相当陌生,我在理解如何正确实现传递给 React 中 setState 的回调以获取受控输入时遇到了一些麻烦.以下代码是我到目前为止所拥有的:
class App 扩展 React.Component {...this.state = {特性: {宽度: '',高度: ''}this.handleChange = this.handleChange.bind(this);//编辑1}句柄变化(e){this.setState(() => ({ properties[e.target.name]: e.target.value }))//编辑 2}使成为(){返回(<输入类型=文本"值={this.state.properties.width}名称=宽度"onChange={this.handleChange}/>...)}}
<块引用>
https://codepen.io/anon/pen/YYQgNv?editors=0010
您需要更改 handleChange
声明:
class App 扩展 React.Component {...handleChange = (e) =>{this.setState({ properties[e.target.name]: e.target.value })}...}
当你写handleChange = (e) =>{...}
它将把函数的 正如@Li357 所指出的,它根本不绑定,相反,它创建了一个类的属性,该属性是一个不绑定 this
指针绑定到你的组件上,这样你就可以访问 setState
this
的箭头函数,捕获了 this
周围作用域的值,即类.
更新:
有人指出使用箭头函数作为类属性是一个实验性的特性,所以在constructor中使用
组件.我得到了使用此代码的示例:this.handleChange = this.handleChange.bind(this)
更安全
handleChange(event) {const target = event.target;this.setState((prevState) => ({属性:{...prevState.properties, ...{ [target.name]: target.value } }}));}
我不完全确定为什么它的行为方式如此,我猜这与 setState
是异步的并且 react
将事件包装在其自己的 SyntheticEvent
,将被重用,并且在调用事件回调后所有属性都将被取消
(参见 react 文档).因此,如果您在 setState
之外存储对 target
的原始引用,它将被限定在 setState
内并使用.
这是一个关于 codesandbox 的工作示例.
<小时>更新 2:
根据react docs,无法访问react SyntheticEvent
以异步方式.处理这个问题的一种方法是调用 event.persist()
这将删除包装器,但这可能不是一个好主意,因为 SyntheticEvent
是一个跨浏览器浏览器原生事件的包装器,以确保事件在所有浏览器中都相同.
I am fairly new to JS and I am having a bit trouble in understanding how to properly implement the callback passed to setState in React, for a controlled input. The following code is what I have so far:
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} />
...
)
}
}
You need to change handleChange
declaration:
class App extends React.Component {
...
handleChange = (e) => {
this.setState({ properties[e.target.name]: e.target.value })
}
...
}
When you write handleChange = (e) => {...}
it will bind as pointed out by @Li357, it doesn't not bind at all, on the contrary it creates a property of the class that is an arrow function that doesn't bind this
pointer of the function to your component so that you will be able to access setState
this
, capturing the this
value of the surrounding scope, the class.
Update:
It has been pointed out that using arrow functions as class properties is an experimental feature, so it is safer to use this.handleChange = this.handleChange.bind(this)
in constructor
of the component.
I got the example working with this code:
handleChange(event) {
const target = event.target;
this.setState((prevState) => ({
properties: {...prevState.properties, ...{ [target.name]: target.value } }
})
);
}
I am not entirely sure why it behaves the way it does, I am guessing it has to do with the fact that setState
is async and react
wraps events in its own SyntheticEvent
which will be reused and all properties will be nullified after the event callback has been invoked
(see react docs). So if you store the original reference to target
outside of setState
it will get scoped and used inside setState
.
Here is a working example on codesandbox.
Update 2:
According to react docs, one can't access react SyntheticEvent
in an asynchronous way. One way of dealing with this would to be call event.persist()
which will remove the wrapper, but this might not be a good idea since SyntheticEvent
is a cross-browser wrapper around the browser’s native event which makes sure the events work identically across all browsers.
这篇关于嵌套状态对象中的回调的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!