【问题标题】:React - uncaught TypeError: Cannot read property 'setState' of undefinedReact - 未捕获的类型错误:无法读取未定义的属性“setState”
【发布时间】:2015-11-25 20:04:53
【问题描述】:

我收到以下错误

未捕获的类型错误:无法读取未定义的属性“setState”

即使在构造函数中绑定了 delta。

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 中,使用 can you use arrow function 进行函数声明来解决这个问题。
  • ^ 这应该是正确答案
  • 我把我的响应函数改成了 ES6,而且,它的工作原理很好。

标签: javascript reactjs


【解决方案1】:

如果在 axios 内部使用,则使用箭头(=>)

axios.get('abc.com').then((response) => {});

【讨论】:

    【解决方案2】:

    如果你使用的是 ES5 语法,那么你需要正确绑定它

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

    如果你使用的是 ES6 及以上版本你可以使用箭头函数,那么你就不需要使用 bind()

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

    【讨论】:

      【解决方案3】:

      这个问题有两种解决方案:

      第一个解决方案是向你的组件添加一个构造函数并像下面这样绑定你的函数:

      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 实际上是指原始上下文

      更多关于绑定函数的信息:

      Bind function Understanding JavaScript Bind ()

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

      Javascript ES6 — Arrow Functions and Lexical this

      【讨论】:

        【解决方案4】:

        箭头函数可以让你的生活更轻松,避免绑定 this 关键字。像这样:

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

        【讨论】:

          【解决方案5】:
          1. 检查状态 检查你是否创建了特定的属性

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

          2.检查(这个) 如果您在任何函数(即 handleChange)中执行 setState,请检查该函数是否绑定到 this 或该函数是否应该是箭头函数。

          ## 将 this 绑定到以下函数的 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)
                  }

          【讨论】:

            【解决方案6】:

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

            • 如果你使用 ES5 语法,那么按照React js Documentation你 必须使用 bind 方法。

              上面的例子是这样的:

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

            • 如果你使用ES6语法,那么你不需要使用bind方法,你可以 这样做:

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

            【讨论】:

              【解决方案7】:

              添加

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

              会解决问题的。 当我们尝试调用 ES6 类的函数时会出现此错误, 所以我们需要绑定方法。

              【讨论】:

                【解决方案8】:

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

                【讨论】:

                  【解决方案9】:

                  您必须使用 this 关键字绑定新事件,如下所述...

                  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>
                          );
                        }
                      }
                  

                  【讨论】:

                    【解决方案10】:

                    你不必绑定任何东西,只需像这样使用箭头函数:

                    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>
                            );
                        }
                    }
                    

                    【讨论】:

                    • 那行有什么区别,请问为什么?
                    • 带有箭头函数的 this 作用域是从上下文继承而来的。对于常规函数,this 总是指最近的函数,而对于箭头函数,这个问题就被消除了,你再也不需要写 var that = this 了。 @RezzagRidha
                    • 从 2019 年开始,这是要走的路 (Y)
                    【解决方案11】:

                    你也可以使用:

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

                    或者:

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

                    如果你传递一些参数..

                    【讨论】:

                    • 在 JSX 中使用箭头函数是不好的做法
                    【解决方案12】:

                    您必须将您的方法与“this”(默认对象)绑定。 所以无论你的函数可能只是在构造函数中绑定它。

                    constructor(props) {
                        super(props);
                        this.state = { checked:false };
                    
                        this.handleChecked = this.handleChecked.bind(this);
                    }
                    
                    handleChecked(){
                        this.setState({
                            checked: !(this.state.checked)
                        })
                    }
                    
                    render(){
                        var msg;
                    
                        if(this.state.checked){
                            msg = 'checked'
                        }
                        else{
                            msg = 'not checked'
                        }
                    
                        return (
                            <div>               
                                <input type='checkbox' defaultChecked = {this.state.checked} onChange = {this.handleChecked} />
                                <h3>This is {msg}</h3>
                            </div>
                        );
                    

                    【讨论】:

                      【解决方案13】:
                      <!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>
                      

                      【讨论】:

                        【解决方案14】:

                        ES7+(ES2016)中可以使用实验性的function bind syntax操作符::进行绑定。它是一种语法糖,与 Davin Tryon 的回答相同。

                        然后您可以将this.delta = this.delta.bind(this); 重写为this.delta = ::this.delta;


                        对于 ES6+ (ES2015) 你也可以使用 ES6+ arrow function (=&gt;) 才能使用this

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

                        为什么?来自 Mozilla 文档:

                        直到箭头函数,每个新函数都定义了自己的 this 值 [...]。事实证明,这对于面向对象的编程风格来说很烦人。

                        箭头函数捕获封闭上下文的 this 值 [...]

                        【讨论】:

                        • 不错的文章详细描述了这一点:reactkungfu.com/2015/07/…
                        • 除了语法之外,使用一个比另一个有什么优势?
                        • 绑定语法更简洁,因为您可以保持方法的正常范围。
                        • 绑定语法不是 ES2016 或 ES2017 的一部分。
                        • @stackoverflow 应该添加向任何答案添加赏金的能力。
                        【解决方案15】:

                        在 React 中使用 ES6 代码时总是使用箭头函数,因为 this 上下文会自动与之绑定

                        使用这个:

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

                        代替:

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

                        【讨论】:

                        • 如果使用箭头函数且参数变量键变量相同,我推荐使用this.setState({videos});跨度>
                        • 这就是为我做的。我是 node 新手,axios 模块的文档与 react 和 setState 不兼容
                        【解决方案16】:

                        虽然这个问题已经有了解决方案,但我只是想分享一下我的问题,希望它可以帮助:

                        /* 
                         * 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() {
                           //....
                           }
                        }
                        

                        【讨论】:

                          【解决方案17】:

                          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>
                          

                          【讨论】:

                          【解决方案18】:

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

                          【讨论】:

                          • 因为我没有重新启动服务器而把我的头发拉出来。
                          【解决方案19】:

                          这是因为 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 类的方法没有正确的词法 this 绑定,那么 ES6 类到底有什么意义,然后甚至不公开直接在其定义上绑定上下文的语法!?
                          • 我理解你的意思,但是如果我在 componentWillMount() 中编写代码,那么我将如何绑定
                          • @sureshpareek 一旦你在构造函数中绑定你的函数,当你从任何生命周期钩子调用它时,它应该被绑定。
                          • @AgmLauncher 我认为这不是 ES6 类本身的问题,而是 React 组件工作方式的问题。
                          • @AgmLauncher 使用 Lambda 函数隐式绑定 this。如果您将delta 定义为delta = () =&gt; { return this.setState({ count: this.state.count++ }); };,该代码也可以工作。在这里解释:hackernoon.com/…
                          猜你喜欢
                          • 2018-07-04
                          • 1970-01-01
                          • 1970-01-01
                          • 2016-08-09
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          • 2020-03-10
                          相关资源
                          最近更新 更多