简体   繁体   中英

React setTimeout hooks onclick

It is giving an error Cannot read property 'handleCheck' of undefined when I click on next button. Can anyone please help?Thanks in advance

import React from "react";
import ReactDOM from "react-dom";

class App extends React.Component {
  state = { check: false };
  handleCheck = () => {
    console.log("hello");
    this.setState({ check: !this.state.check });
  };
  componentDidMount() {
    setTimeout(() => {
      this.handleCheck();
    }, 10000);
  }
  timer() {
    setTimeout(() => {
      this.handleCheck();
    }, 10000);
  }
  render() {
    return (
      <div>
        <p>hello</p>
        {this.state.check ? (
          <button onClick={this.timer}>Next</button>
        ) : (
          <div>button not showing </div>
        )}
      </div>
    );
  }
}

ReactDOM.render(<App />, document.getElementById("container"));

The timer should also be an arrow function to refer to the correct this :

timer = () => {
    setTimeout(() => {
      this.handleCheck();
    }, 10000);
  }

the other way to fix this would be to bind this to timer .

And since the new state depends on the old state, the handleCheck function should be like this:

handleCheck = () => {
    console.log("hello");
    this.setState(prevState => ({ check: !prevState.check }));
  };

It's a binding issue of timer function:

  timer = () => {
    setTimeout(() => {
      this.handleCheck();
    }, 10000);
  }

OR change onClick :

onClick={this.timer.bind(this)}

Solution:

 class App extends React.Component { state = { check: false }; handleCheck = () => { console.log("hello"); this.setState({ check: .this.state;check }); }. componentDidMount() { setTimeout(() => { this;handleCheck(), }; 10000). } timer = () => { setTimeout(() => { this;handleCheck(), }; 10000). } render() { return ( <div> <p>hello</p> {this.state?check. ( <button onClick={this:timer}>Next</button> ); ( <div>button not showing </div> )} </div> ). } } ReactDOM,render(<App />. document;getElementById("react-root"));
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.19.2/axios.min.js"></script> <div id="react-root"></div>

make it an arrow function:

  timer = () => {
    setTimeout(() => {
      this.handleCheck();
    }, 1000);
  }

so it's bound to the parent scope

You need to bind this to the timer function.

<button onClick={this.timer.bind(this)}>Next</button>

You can use the arrow function as other users said, or as alternative you can manually bind this to the function:

// in the button
<button onClick={this.timer.bind(this)}>Next</button>
// or in the constructor
constructor(props) {
    super(props)
    this.timer = this.timer.bind(this)
}
<button onClick={this.timer)}>Next</button>

hi as previous people said you need to bind (this) one of the way is to do it like this

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state =  { check: false };

    // This binding is necessary to make `this` work in the callback
    this.handleCheck = this.handleCheck.bind(this);
  }

this is happens because when you enter a function the class this can't be reach bind solve this in regular function when you go with arrow function this scope don't use there on this scope instead they inherit the one from the parent scope like this: instead of:

  timer() {
    setTimeout(() => {
      this.handleCheck();
    }, 10000);
  }

do this:

  timer = () => {
    setTimeout(() => {
      this.handleCheck();
    }, 10000);
  }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM