首页 文章

React - uncaught TypeError:无法读取未定义的属性'setState'

提问于
浏览
175

我收到以下错误

未捕获的TypeError:无法读取未定义的属性'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>
        );
    }
}

11 回答

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

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

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

    ES7+ (ES2016)中,您可以使用实验function bind syntax运算符 :: 进行绑定 . 这是一个语法糖,将与Davin Tryon的答案一样 .

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


    对于 ES6+ (ES2015),您也可以使用ES6 arrow function=> )来使用 this .

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

    为什么?来自Mozilla文档:

    在箭头函数之前,每个新函数都定义了自己的这个值[...] . 事实证明,这是一种面向对象的编程风格 . 箭头函数捕获封闭上下文的这个值[...]

  • 0
    <!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>
    
  • 5

    这是因为 this.delta 没有绑定到 this .

    为了在构造函数中绑定set this.delta = this.delta.bind(this)

    constructor(props) {
        super(props);
    
        this.state = {
            count : 1
        };
    
        this.delta = this.delta.bind(this);
    }
    

    目前,您正在调用bind . 但是bind返回一个绑定函数 . 您需要将函数设置为其绑定值 .

  • 0

    您必须使用'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>
        );
    
  • 4

    您必须使用 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>
            );
          }
        }
    
  • 25

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

  • 16

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

    Use this:

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

    instead of:

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

    您还可以使用:

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

    要么:

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

    如果你传递一些参数..

  • 5

    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>
    

相关问题