2017-01-02 73 views
3

我正在重寫一些舊的ReactJS代碼,並且卡住了修復此錯誤(該錯誤在控制檯中重複約1700次,DOM不呈現在所有):ES6 - 警告:setState(...):在現有狀態轉換期間無法更新

警告:的setState(...):現有狀態 轉變(如render或其他部件的構造 )內時不能更新。渲染方法應該是道具和純粹功能的狀態;構造函數的副作用是反模式,但可以將 移動到componentWillMount

我是一個組件,它將狀態傳遞給應該呈現某些控件的組件。基於點擊的控件,狀態應該改變,新的控件應該呈現。

所以這是我的容器組件:

class TeaTimer extends Component { 
    constructor(props) { 
     super(props); 
     this.state = { 
      count: 120, 
      countdownStatus: 'started' 
     } 
    } 

    componentDidUpdate(prevProps, prevState) { 
     if (this.state.countdownStatus !== prevState.countdownStatus) { 
      switch (this.state.countdownStatus) { 
       case 'started': 
        this.startTimer(); 
        break; 
       case 'stopped': 
        this.setState({count:0}); 
      } 
     } 
    } 

    componentWillUnmount() { 
     clearInterval(this.timer); 
     delete this.timer; 
    } 

    startTimer() { 
     this.timer = setInterval(() => { 
      let newCount = this.state.count -1; 
      this.setState({ 
       count: newCount >= 0 ? newCount : 0 
      }); 
      if(newCount === 0) { 
       this.setState({countdownStatus: 'stopped'}); 
      } 
     }, 1000) 
    } 

    handleStatusChange(newStatus) { 
     this.setState({ countdownStatus: newStatus }); 
    } 

    render() { 
     let {count, countdownStatus} = this.state; 
     let renderStartStop =() => { 
      if (countdownStatus !== 'stopped') { 
       return <StartStop countdownStatus={countdownStatus} onStatusChange={this.handleStatusChange()}/> 
      } else { 
       return <div>This will be the slider form</div> 
      } 
     }; 
     return(
      <div className={styles.container}> 
       <p>This is the TeaTimer component</p> 
       <Clock totalSeconds={count}/> 
       {renderStartStop()} 
      </div> 
     ) 
    } 
} 

這是我的控制組件:

class StartStop extends Component { 
    constructor(props) { 
     super(props); 
    } 

    onStatusChange(newStatus) { 
     return() => { 
      this.props.onStatusChange(newStatus); 
     } 
    } 

    render() { 
     let {countdownStatus} = this.props; 

     let renderStartStopButton =() => { 
      if(countdownStatus === 'started') { 
       return <button onClick={()=> this.onStatusChange('stopped')}>Reset</button>; 
      } else { 
       return <button onClick={()=> this.onStatusChange('started')}>Start</button> 
      } 
     }; 

     return(
      <div className={styles.tt.Controls}> 
       {renderStartStopButton()} 
      </div> 
     ) 
    } 
} 

StartStop.propTypes = { 
    countdownStatus: React.PropTypes.string.isRequired, 
    onStatusChange: React.PropTypes.func.isRequired 
}; 

我對文字的牆很抱歉,但我真的;噸揣摩出錯誤來自於 - 因此不知道我可以忽略哪部分代碼。

我嘗試過在seemingly related question中找到的解決方案,但無法使其工作。

+0

你能嘗試使用這一行'返回',看看能否解決? –

+0

@FabianSchultz這解決了我最初的問題:) –

回答

7

我覺得你在這一行一個錯字:

return <StartStop countdownStatus={countdownStatus} onStatusChange={this.handleStatusChange()}/> 

它應該是:

return <StartStop countdownStatus={countdownStatus} onStatusChange={() => this.handleStatusChange}/> 

你似乎調用該方法,而不是handleStatusChange傳遞它作爲一個回調。

+2

onStatusChange = {this.handleStatusChange} – 2017-08-24 10:40:53

-1

在你的return <StartStop countdownStatus={countdownStatus} onStatusChange={this.handleStatusChange()}/>的這一行給出了警告,在按下一個試圖通過setState關鍵字改變狀態的按鈕時調用handleStatusChanged函數。每當狀態改變時,再次調用render函數,但在你的情況下render函數正在返回,而render函數被setState關鍵字再次調用。

0

您的metod互相呼叫,因此您必須定義metod的兩個實例。

class StartStop extends Component { 
    constructor(props) { 
     super(props); 
     this.onStatusChangeReset=this.onStatusChange.bind(this); 
     this.onStatusChangeStart=this.onStatusChange.bind(this); 

    } 

    onStatusChange(newStatus) { 
     return() => { 
      this.props.onStatusChange(newStatus); 
     } 
    } 

    render() { 
     let {countdownStatus} = this.props; 

     let renderStartStopButton =() => { 
      if(countdownStatus === 'started') { 
       return <button onClick={this.onStatusChangeReset('stopped')}>Reset</button>; 
      } else { 
       return <button onClick={this.onStatusChangeStart('started')}>Start</button> 
      } 
     }; 

     return(
      <div className={styles.tt.Controls}> 
       {renderStartStopButton()} 
      </div> 
     ) 
    } 
} 

StartStop.propTypes = { 
    countdownStatus: React.PropTypes.string.isRequired, 
    onStatusChange: React.PropTypes.func.isRequired 
}; 
相關問題