javascript - 未捕获的类型错误 : Cannot read property 'setState' of undefined

标签 javascript reactjs webpack

我试图使用 web-pack 渲染简单的 React 应用程序,所有内容都可以完美编译。运行时代码失败并显示以下堆栈跟踪:

Uncaught TypeError: Cannot read property 'setState' of undefined
at checkBoxCheck (App.js:174)...

这是带有 setState 的代码:

//App.js
export class Login extends Component {
  constructor(props) {
    super(props);
    this.state = { remember: false };
  }

  checkBoxCheck(event) {
    this.setState({
      remember: !this.state.remember
    });
    console.log(this.state.remember);
  }

  render() {
    let msg = this.state.remember ? "checked" : "uncheked";
    return (
      <form method="post">
        <h1>{msg}</h1>
        <label htmlFor="login">Login: </label>
        <input type="text" name="login" />
        <label htmlFor="pass"> Password: </label>
        <input type="password" name="pass" />
        <label htmlFor="remember">Remeber me: </label>
        <input
          type="checkbox"
          name="remember"
          defaultChecked={this.state.remember}
          onChange={this.checkBoxCheck}
        />
      </form>
    );
  }
}

语法问题出在哪里?

我还尝试创建一个 checkBoxCheck '箭头' 函数,这会导致编译错误:

    checkBoxCheck = event => {
    this.setState((prevState, props) =>({
        remember: !prevState.remember
    }));
    console.log(this.state.remember);
}

//output        
SyntaxError: D:/Projects/Learning-projects/learn-react/src/App.js: Unexpected token (53:18)

  51 |     }
  52 |
> 53 |     checkBoxCheck = event => {
     |                   ^
  54 |         this.setState((prevState, props) =>({
  55 |             remember: !prevState.remember
  56 |         }));

最佳答案

您实际上忘记将上下文绑定(bind)到 checkBoxCheck 方法。

...
<input
   type="checkbox"
   name="remember"
   defaultChecked={this.state.remember}
   onChange={this.checkBoxCheck.bind(this)} // <- .bind(this)
/>
...
<小时/>

提示:

关于您的代码很少有评论:

  1. 不要在render方法中绑定(bind)上下文。
  2. 请勿在 this.setState 函数中使用 this.state

永远不要在渲染中使用.bind()

render() { // <- If you here
  ...
  <input
    ...
    onChange={this.checkBoxCheck.bind(this)} // <- don't do this
  />
  ...
}

通过像这样绑定(bind)事件处理程序,每次 React 调用组件的渲染时,您都可以创建全新的函数。相反,您可以将函数转换为箭头函数:

checkBoxCheck = event => {
  this.setState({
    remember: !this.state.remember
  });
  console.log(this.state.remember);
}

并这样调用它:

...
<input
   type="checkbox"
   name="remember"
   defaultChecked={this.state.remember}
   onChange={this.checkBoxCheck} // <- there is no binding
/>
...

此外,您可以在类构造函数中绑定(bind)所有方法:

//App.js
export class Login extends Component {
  constructor(props) {
    super(props);
    this.state = { remember: false };

    this.checkBoxCheck = this.checkBoxCheck.bind(this); // <- Bind your methods here
  }
...

并在不绑定(bind)的情况下调用您的函数:

...
<input
   type="checkbox"
   name="remember"
   defaultChecked={this.state.remember}
   onChange={this.checkBoxCheck} // <- there is no binding
/>
...

this.setState 中使用 this.state

增量函数就是一个例子:

function increment() {
  this.setState({value: this.state.value + 1});
}

如果这两个 setState 操作在一个批处理中分组在一起,则其看起来将类似于以下内容(假定值为 1):

setState({value: 1 + 1})
setState({value: 1 + 1})

可以通过使用将先前状态作为第一个参数的回调来避免这种情况:

function increment() {
  this.setState(prevState => ({value: prevState.value + 1}));
}

然后,即使事情是批量发生的,React 也会以正确且更新的状态调用参数。上面的例子类似于:

setState({value: 1 + 1})
setState({value: 2 + 1})

引用资料:

关于javascript - 未捕获的类型错误 : Cannot read property 'setState' of undefined,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51254873/

相关文章:

typescript - 模块构建失败 : Error: Could not find file: '[my-project-directory]\src\App.vue'

angular - 我是否有多个导出常量实例或多次导入时有一个实例?

javascript - 在 highcharts 中交叉时突出显示区域图表线

css - 将自定义 css 添加到 React-Bootstrap 组件

javascript - document.createElement : el. 大小 = "2%"不起作用

reactjs - 出现错误 : void' is not assignable to type 'FC<IPickWinnerProps>' in react js

reactjs - 错误: Invariant failed: You should not use <Switch> outside a <Router> even though my structure is good

sass - 将 sass 集成到 Angular 模板 Visual Studio 中

javascript - 在javascript中选择并添加类

javascript - 未定义或空引用文件的错误 :"Unable to get property ' 内容'