开发者问题收集

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

2015-08-31
437699

我收到以下错误

Uncaught TypeError: Cannot read property 'setState' of undefined

即使在构造函数中绑定 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 返回一个绑定函数。您需要将该函数设置为其绑定值。

Davin Tryon
2015-08-31

ES7+ (ES2016) 中,您可以使用实验性的 函数绑定语法 运算符 :: 进行绑定。它是一种语法糖,其作用与 Davin Tryon 的答案相同。

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


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

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

为什么?来自 Mozilla 文档:

Until arrow functions, every new function defined its own this value [...]. This proved to be annoying with an object-oriented style of programming.

Arrow functions capture the this value of the enclosing context [...]

Fabien Sa
2015-12-10

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>
Tao Wang
2016-06-04