嵌套状态对象中的回调 [英] callback in nested state object

查看:59
本文介绍了嵌套状态对象中的回调的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对 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) =>{...} 它将把函数的 this 指针绑定到你的组件上,这样你就可以访问 setState正如@Li357 所指出的,它根本不绑定,相反,它创建了一个类的属性,该属性是一个不绑定 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} />
        ...
       )
   }      
}

https://codepen.io/anon/pen/YYQgNv?editors=0010

解决方案

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 this pointer of the function to your component so that you will be able to access setState 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, 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆