Shukai Ni
Shukai Ni

Reputation: 467

Update react state after a certain interval

constructor(){
    super();
    this.state={
        data : [1,2,3,4,1,2,3,4,1,3,1,4,12,2,3,2]
    };

}
componentDidMount(){setInterval(this.updateCanvas(),5000);}

updateCanvas() {
    console.log(this.props.newData);
    let data = this.state.data.slice();
    let length = data.length;
    console.log(length);
    data.push(20);
    this.setState({data:data},()=>{console.log(this.state.data);});
}

I am trying to push a new value to the state every 5s, but the state changes immediately. How can I achieve the effect I want?

Upvotes: 0

Views: 1308

Answers (3)

Pineda
Pineda

Reputation: 7593

The state changes immediate because you are invoking the callback method you pass to setInterval immediately on this line by adding parenthesis to it:

setInterval(this.updateCanvas(),5000);
//---------------------------^
// Adding these to function will invoke it

The solution is to pass the reference to the function without the parenthesis (and they're not invoking it immediately)

setInterval(this.updateCanvas,5000);

Upvotes: 3

Ori Drori
Ori Drori

Reputation: 191976

Why doesn't it work?

There are actually two problems:

  1. You need to pass a function to setInterval. The setInterval method excepts a function as it's 1st parameter. When you usesetInterval(this.updateCanvas(),5000);, you pass the returned value of the invoked method this.updateCanvas(). Since the method returns nothing (undefined), what you actually get is window.setInterval(undefined, 5000);.

  2. You have to bind that function to the component instance's this. Since the updateCanvas method uses this, for example this.setState(),

Binding updateCanvas to this and invoking in setInterval:

  • Pass setInveral an arrow function, and invoke updateCanvas inside:

    componentDidMount(){
        setInterval(() => this.updateCanvas(),5000);
    }
    

Or

  • Bind the method to the component instance this:

    constructor(){
        super();
        this.state={
            data : [1,2,3,4,1,2,3,4,1,3,1,4,12,2,3,2]
        };
    
        this.updateCanvas = this.updateCanvas.bind(this); // bind the method to this
    }
    
    componentDidMount(){
        setInterval(this.updateCanvas,5000);
    }
    

Upvotes: 0

derp
derp

Reputation: 2308

Remove that bracket from this.updateCanvas(). Ie setInterval(this.updateCanvas, 5000);}

The first will execute the function immediately whilst the second passes it in as a function for set interval

Upvotes: 1

Related Questions