2016-07-27 58 views
0

我是新來ReactJS和我似乎無法找出爲什麼下面的setState的結果並不像我期望它(即增加值每秒1)的setState在ReactJS

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

class Layout extends React.Component { 

    constructor() { 
     super(); 
     this.state = { 
      name: "Behnam", 
      i: 0 
     } 
    } 

    render() { 

     setInterval(() => { 
      this.setState({ name : "Behnam" + this.state.i }); 
      this.setState({ i: this.state.i + 1 }); 
     }, 1000); 

     return (
      <div className="container"> 
       {this.state.name} 
      </div> 
     ); 
    } 
} 

ReactDOM.render(<Layout />, document.getElementById('app')); 

相反,輸出字符串會迅速增加(我猜測反應速度與嘗試保持虛擬DOM更新一樣快)。所以我想知道什麼是正確的方法來做到這一點?

+1

你做錯了。知道setState會觸發渲染方法,所以在你的代碼中,你已經做了一些循環的渲染> setState> render> setState ....好的方法是把setInterval放在組件生命週期的組件生命週期(https:/ /facebook.github.io/react/docs/component-specs.html),所以你的渲染將只是聲明性的 –

回答

4

每次更改狀態時,都會重新渲染組件。 因爲您在渲染方法中啓動了setInterval,所以會得到另一個更改狀態的時間間隔以及重新展開等等。

移動setIntervalcomponentDidMount,其被調用一次,當組件安裝件:

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

class Layout extends React.Component { 

    constructor() { 
     super(); 
     this.state = { 
      name: "Behnam", 
      i: 0 
     } 
    } 

    componentDidMount() { set the interval after the component mounted, and save the reference 
     this.interval = setInterval(() => { 
      this.setState({ 
       name: `Behnam${this.state.i}`, 
       i: this.state.i + 1 
      }); 
     }, 1000); 
    } 

    componentWillUnmount() { 
     this.interval && clearInterval(this.interval); // clear the interval when the component unmounts 
    } 

    render() { 
     return (
      <div className="container"> 
       {this.state.name} 
      </div> 
     ); 
    } 
} 

ReactDOM.render(<Layout />, document.getElementById('app')); 
1

目前,它是建立一個間隔時間的成分呈現,所以有多個計時器遞增價值。您可能想要在componentDidMount()而不是render()中執行此操作。見docs

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

class Layout extends React.Component { 

    constructor() { 
     super(); 
     this.state = { 
      name: "Behnam", 
      i: 0 
     } 
    } 

    componentDidMount() { 
     setInterval(() => { 
      this.setState({ name : "Behnam" + this.state.i }); 
      this.setState({ i: this.state.i + 1 }); 
     }, 1000); 
    } 

    render() { 
     return (
      <div className="container"> 
       {this.state.name} 
      </div> 
     ); 
    } 
} 

ReactDOM.render(<Layout />, document.getElementById('app')); 
1

每次渲染被觸發時,你又打電話setInterval,增加了網頁上的活躍間隔數。

你或許應該用另外一個生命週期方法,如componentDidMount。您應該記住保存由setInterval返回的區間ID,以便您可以撥打clearIntervalcomponentWillUnmount