React - uncaught TypeError:无法读取undefined的属性'setState'

Dan*_*ter 284 javascript reactjs

我收到以下错误

未捕获的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>
        );
    }
}
Run Code Online (Sandbox Code Playgroud)

Dav*_*yon 403

这是由于this.delta不受约束this.

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

constructor(props) {
    super(props);

    this.state = {
        count : 1
    };

    this.delta = this.delta.bind(this);
}
Run Code Online (Sandbox Code Playgroud)

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

  • 如果他们的方法没有正确的词法`this`绑定,那么ES6类的重点是什么,然后甚至不公开用于直接在其定义上绑定其上下文的语法!? (171认同)
  • 来自android / java世界,我感到困惑 (3认同)
  • @sureshparek 一旦你在构造函数中绑定了你的函数,那么当你从任何生命周期钩子调用它时它应该被绑定。 (2认同)
  • @AgmLauncher使用Lambda函数隐式绑定此函数。如果您将delta定义为delta =()=&gt; {返回this.setState({count:this.state.count ++}); };`代码也将起作用。在这里解释:https://hackernoon.com/javascript-es6-arrow-functions-and-lexical-this-f2a3e2a5e8c4 (2认同)

Fab*_* Sa 129

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
    });
}
Run Code Online (Sandbox Code Playgroud)

为什么?来自Mozilla文档:

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

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

  • 很好的文章详细描述了这个:http://reactkungfu.com/2015/07/why-and-how-to-bind-methods-in-your-react-component-classes/ (3认同)
  • 绑定语法更简洁,因为您可以保留方法的常规范围。 (2认同)
  • @stackoverflow 应该添加为任何答案添加赏金的能力。 (2认同)

小智 29

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>
            );
    }
});
Run Code Online (Sandbox Code Playgroud)

这是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>
            );
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,除了类实现中的语法差异外,事件处理程序绑定存在差异.

在ES5版本中,它是

              <button onClick={this.delta}>+</button>
Run Code Online (Sandbox Code Playgroud)

在ES6版本中,它是:

              <button onClick={this.delta.bind(this)}>+</button>
Run Code Online (Sandbox Code Playgroud)


Ign*_*rew 22

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

用这个:

(videos) => {
    this.setState({ videos: videos });
    console.log(this.state.videos);
};
Run Code Online (Sandbox Code Playgroud)

代替:

function(videos) {
    this.setState({ videos: videos });
    console.log(this.state.videos);
};
Run Code Online (Sandbox Code Playgroud)

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

Gab*_*uiz 19

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

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>
        );
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 带有箭头函数的此范围继承自上下文.对于常规函数,这总是指最近的函数,而使用箭头函数时,这个问题就被删除了,你不需要再次写var = this.@RezzagRidha (3认同)

小智 9

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

this.delta = this.delta.bind(this)
Run Code Online (Sandbox Code Playgroud)

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

delta = () => {
    // do something
  }
Run Code Online (Sandbox Code Playgroud)


Nee*_*tel 7

你必须用这个关键字绑定新事件,正如我在下面提到的......

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>
        );
      }
    }
Run Code Online (Sandbox Code Playgroud)


Mse*_*Ali 7

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

\n\n

第一个解决方案是向组件添加构造函数并绑定函数,如下所示:

\n\n
constructor(props) {\n        super(props);\n\n        ...\n\n        this.delta = this.delta.bind(this);\n    }\n
Run Code Online (Sandbox Code Playgroud)\n\n

所以这样做:

\n\n
this.delta = this.delta.bind(this); \n
Run Code Online (Sandbox Code Playgroud)\n\n

而不是这个:

\n\n
this.delta.bind(this);\n
Run Code Online (Sandbox Code Playgroud)\n\n

第二种解决方案是使用箭头函数:

\n\n
delta = () => {\n       this.setState({\n           count : this.state.count++\n      });\n   }\n
Run Code Online (Sandbox Code Playgroud)\n\n

实际上箭头函数并不绑定它\xe2\x80\x99s 自己的this。箭头在词法上作用于bind它们的上下文,因此this实际上指的是原始上下文

\n\n

有关绑定功能的更多信息:

\n\n

Bind 函数\n理解 JavaScript Bind()

\n\n

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

\n\n

Javascript ES6 \xe2\x80\x94 箭头函数和词法this

\n


Jar*_*enc 6

您还可以使用:

<button onClick={()=>this.delta()}>+</button>
Run Code Online (Sandbox Code Playgroud)

要么:

<button onClick={event=>this.delta(event)}>+</button>
Run Code Online (Sandbox Code Playgroud)

如果你传递一些参数..


har*_*ugh 6

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

  • 如果您使用ES5语法,那么根据React js 文档,您必须使用绑定方法。

    对于上面的例子来说是这样的:

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

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

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


Ani*_*nil 5

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


Sha*_*war 5

您必须使用'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>
    );
Run Code Online (Sandbox Code Playgroud)