我收到以下错误


未捕获的TypeError:即使在构造函数中绑定了增量之后,也无法读取未定义的属性'setState'


。 br />
class Counter extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            count : 1
        };

        this.delta.bind(this);
    }

    delta() {
        this.setState({
            count : this.state.count++
        });
    }

    render() {
        return (
            <div>
                <h1>{this.state.count}</h1>
                <button onClick={this.delta}>+</button>
            </div>
        );
    }
}


评论

在ES6中,可以使用箭头函数进行函数声明来解决此问题。

^这应该是正确的答案

我将响应功能更改为ES6,并且hurrey正常运行。

#1 楼

这是由于this.delta未绑定到this

为了绑定构造函数中的this.delta = this.delta.bind(this)集:

constructor(props) {
    super(props);

    this.state = {
        count : 1
    };

    this.delta = this.delta.bind(this);
}

调用绑定。但是bind返回一个绑定函数。您需要将函数设置为其绑定值。

评论


如果ES6类的方法没有适当的词法绑定,那么甚至不公开直接在其定义上绑定其上下文的语法,这到底是什么呢?

– AgmLauncher
16-10-18在0:34

我明白你的意思,但是如果我在componentWillMount()中编写代码,那么我将如何绑定

–确保放心
17年7月31日在12:54

@sureshpareek一旦将函数绑定到构造函数中,则从任何生命周期挂钩调用函数时都应将其绑定。

–李维·富勒(Levi Fuller)
17年11月20日在21:48

来自android / java世界,我很困惑

–都铎王朝
18年5月5日在20:48

@AgmLauncher使用Lambda函数隐式绑定此函数。如果您将delta定义为delta =()=> {返回this.setState({count:this.state.count ++}); };该代码也将起作用。在这里解释:hackernoon.com/…

– K. Rhoda
19年4月10日在17:25

#2 楼

在ES7 +(ES2016)中,可以使用实验性功能绑定语法运算符::进行绑定。这是一种语法糖,将与Davin Tryon的答案相同。才能使用this.delta = this.delta.bind(this);
delta = () => {
    this.setState({
        count : this.state.count + 1
    });
}

为什么?在Mozilla doc中,直到箭头函数,每个新函数都定义了自己的此值[...]。这证明是令人讨厌的一种面向对象的编程风格。
箭头函数捕获了封闭上下文的这个值。

评论


不错的文章详细描述了这一点:reactkungfu.com/2015/07/…

–江户
16年6月9日在10:59

除了语法外,使用一个相比另一个还有什么好处?

– Jeremy D
16年11月8日在19:52

绑定语法更简洁,因为您可以保留方法的常规范围。

–法比安·萨(Fabien Sa)
16年11月8日在22:02

绑定语法不属于ES2016或ES2017。

–费利克斯·克林(Felix Kling)
17年9月22日在14:12

@stackoverflow应该增加向任何答案添加赏金的功能。

–加布
18-10-8在5:27

#3 楼

ES5和ES6类之间的上下文有所不同。因此,实现之间也会有一些差异。

这是ES5版本:

 var Counter = React.createClass({
    getInitialState: function() { return { count : 1 }; },
    delta: function() {
        this.setState({
            count : this.state.count++
        });
    },
    render: function() {
        return (
            <div>
              <h1>{this.state.count}</h1>
              <button onClick={this.delta}>+</button>
            </div>
            );
    }
});
 




,这是ES6版本:

 class Counter extends React.Component {
    constructor(props) {
        super(props);
        this.state = { count : 1 };
    }

    delta() {
        this.setState({
            count : this.state.count++
        });
    }

    render() {
        return (
            <div>
              <h1>{this.state.count}</h1>
              <button onClick={this.delta.bind(this)}>+</button>
            </div>
            );
    }
}
 




请注意,除了类实现中的语法不同之外,事件处理程序绑定也有所不同。

在ES5版本中,它是

              <button onClick={this.delta}>+</button>


在ES6版本中,它是:

              <button onClick={this.delta.bind(this)}>+</button>


评论


在JSX中使用箭头功能或绑定是一种不好的做法。 stackoverflow.com/questions/36677733/…。

–法比安·萨(Fabien Sa)
17-10-22在13:26

#4 楼

在React中使用ES6代码时,请始终使用箭头函数,因为此上下文会自动与之绑定

使用此函数: :

(videos) => {
    this.setState({ videos: videos });
    console.log(this.state.videos);
};


评论


如果使用箭头功能并且参数变量与键变量相同,则建议将其用作this.setState({videos});。

–jayeshkv
17年7月29日在22:13



这就是为我做的。我是Node的新手,并且axios模块的文档与react和setState不兼容

–dabobert
19年1月2日在22:05

#5 楼

您不必绑定任何东西,只需使用如下箭头功能:

 class Counter extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            count: 1
        };

    }
    //ARROW FUNCTION
    delta = () => {
        this.setState({
            count: this.state.count++
        });
    }

    render() {
        return (
            <div>
                <h1>{this.state.count}</h1>
                <button onClick={this.delta}>+</button>
            </div>
        );
    }
}
 


评论


那行得通,有什么区别,为什么?

– Ridha Rezzag
18年11月4日在1:33

带有箭头功能的作用域是从上下文继承的。对于常规函数,这始终指的是最接近的函数,而对于箭头函数,此问题已消除,并且您无需再次编写var that = this。 @RezzagRidha

–加博·鲁伊斯(Gabo Ruiz)
18年11月6日,3:30

截至2019年,这是要走的路(是)

–PolarBear10
19年5月5日在16:24

#6 楼

您必须将方法与“此”(默认对象)绑定。
因此,无论您的函数是什么,都只需将其绑定到构造函数中即可。

#7 楼

您还可以使用:

<button onClick={()=>this.delta()}>+</button>


或:

<button onClick={event=>this.delta(event)}>+</button>


如果要传递一些参数。 br />

评论


在JSX中使用箭头功能是不好的做法

–加布
18-10-9在3:56

#8 楼

您需要将此绑定到构造函数,并记住对构造函数的更改需要重新启动服务器。否则,您将遇到相同的错误。

评论


因为没有重新启动服务器,所以正在拔头发。

–kurtcorbett
16年1月27日在7:10

#9 楼

此错误可以通过多种方法解决-



如果您使用的是ES5语法,那么根据React js文档,您必须使用bind方法。 br />
上面的示例是这样的:

this.delta = this.delta.bind(this)


如果使用的是ES6语法,则无需使用bind方法,您可以
使用以下方法进行操作:

delta=()=>{ this.setState({ count : this.state.count++ }); }



#10 楼

您必须将新事件与此关键字绑定,正如我在下面提到的...

class Counter extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            count : 1
        };

        this.delta = this.delta.bind(this);
    }

    delta() {
        this.setState({
            count : this.state.count++
        });
    }

    render() {
        return (
            <div>
                <h1>{this.state.count}</h1>
                <button onClick={this.delta}>+</button>
            </div>
        );
      }
    }


#11 楼

箭头功能可以使您的生活更加轻松,避免绑定此关键字。像这样:

 delta = () => {
       this.setState({
           count : this.state.count++
      });
   }


#12 楼

此问题有两种解决方案:

第一种解决方案是在组件中添加构造函数并像下面这样绑定函数:

constructor(props) {
        super(props);

        ...

        this.delta = this.delta.bind(this);
    }


这样做:

this.delta = this.delta.bind(this); 


而不是这样:

this.delta.bind(this);


第二种解决方法是使用箭头函数代替:

delta = () => {
       this.setState({
           count : this.state.count++
      });
   }


实际上箭头函数不绑定它自己的this。箭头函数按词法bind的上下文,因此this实际上是指原始上下文。有关绑定函数的更多信息:

绑定函数
了解JavaScript Bind()

有关箭头函数的更多信息:

Javascript ES6 —箭头函数和词法this

#13 楼

只需将您的bind语句从必须的内容更改为 => this.delta = this.delta.bind(this);

#14 楼

添加


onClick = {this.delta.bind(this)}


将解决此问题。我们尝试调用ES6类的函数,
,因此我们需要绑定该方法。

#15 楼

尽管这个问题已经有了解决方案,但我只想分享我的问题以使其得到解决,希望可以对您有所帮助:

/* 
 * The root cause is method doesn't in the App's context 
 * so that it can't access other attributes of "this".
 * Below are few ways to define App's method property
 */
class App extends React.Component {
  constructor() {
     this.sayHi = 'hello';
     // create method inside constructor, context = this
     this.method = ()=> {  console.log(this.sayHi) };

     // bind method1 in constructor into context 'this'
     this.method1 = this.method.bind(this)
  }

  // method1 was defined here
  method1() {
      console.log(this.sayHi);
  }

  // create method property by arrow function. I recommend this.
  method2 = () => {
      console.log(this.sayHi);
  }
   render() {
   //....
   }
}


#16 楼

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Hello World</title>

    <script src="https://unpkg.com/react@0.14.8/dist/react.min.js"></script>
    <script src="https://unpkg.com/react-dom@0.14.8/dist/react-dom.min.js"></script>
    <script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>

  </head>
  <body>
  <div id="root"></div>
    <script type="text/babel">

        class App extends React.Component{

            constructor(props){
                super(props);
                this.state = {
                    counter : 0,
                    isToggle: false
                }
            this.onEventHandler = this.onEventHandler.bind(this);   
            }

            increment = ()=>{
                this.setState({counter:this.state.counter + 1});
            }

            decrement= ()=>{
                if(this.state.counter > 0 ){
                this.setState({counter:this.state.counter - 1});    
                }else{
                this.setState({counter:0});             
                }
            }
            // Either do it as onEventHandler = () => {} with binding with this  // object. 
            onEventHandler(){
                this.setState({isToggle:!this.state.isToggle})
                alert('Hello');
            }


            render(){
                return(
                    <div>
                        <button onClick={this.increment}> Increment </button>
                        <button onClick={this.decrement}> Decrement </button>
                        {this.state.counter}
                        <button onClick={this.onEventHandler}> {this.state.isToggle ? 'Hi':'Ajay'} </button>

                    </div>
                    )
            }
        }
        ReactDOM.render(
        <App/>,
        document.getElementById('root'),
      );
    </script>
  </body>
  </html>


#17 楼



检查状态
检查状态是否创建特定的属性




 this.state = {
            name: "",
            email: ""
            }
            
           
            
this.setState(() => ({ 
             comments: comments          //comments not available in state
             }))  





2.检查(this)
如果在任何函数(例如handleChange)中执行setState,请检查该函数是否绑定到this或该函数应该是箭头函数。 br />
## 3种将其绑定到以下功能的方法##




 //3 ways for binding this to the below function

handleNameChange(e) {  
     this.setState(() => ({ name }))
    }
    
// 1.Bind while callling function
      onChange={this.handleNameChange.bind(this)}
      
      
//2.make it as arrow function
     handleNameChange((e)=> {  
     this.setState(() => ({ name }))
     })
    
//3.Bind in constuctor 

constructor(props) {
        super(props)
        this.state = {
            name: "",
            email: ""
        }
        this.handleNameChange = this.handleNameChange.bind(this)
        } 




#18 楼

如果您使用的是ES5语法,则需要正确地绑定它

this.delta = this.delta.bind(this)


,如果您使用的是ES6及更高版本,则可以使用箭头功能,则不需要使用bind()它

delta = () => {
    // do something
  }