提问者:小点点

React-未捕获的TypeError:无法读取未定义的属性“set state”


我得到以下错误

未捕获的TypeError:无法读取未定义的属性“set state”

即使在构造函数中绑定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>
        );
    }
}

共3个答案

匿名用户

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

为了绑定,在构造函数中设置this.delta=this.delta.bind(this):

constructor(props) {
    super(props);

    this.state = {
        count : 1
    };

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

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

匿名用户

在ES7+(ES2016)中,您可以使用实验性函数bind语法操作符::进行绑定。这是一个句法糖,将做同样的戴文特雷翁的答案。

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

对于ES6+(ES2015),您还可以使用ES6+箭头函数(=>)来使用this

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

为什么?来自Mozilla文档:

在arrow函数之前,每个新函数都定义了自己的这个值[...]。对于面向对象的编程风格,这被证明是令人讨厌的。

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

匿名用户

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>