2017-04-05 96 views
0

我有一個時間選擇器,我想將該值設置爲this.state.start。然而,this.state.start的值可能等於this.props.normalthis.props.spec,具體取決於用戶是否設置了特殊小時數,如果他們沒有,那麼它會回落到使用正常小時數。在React中渲染組件時有條件地更新this.state?

我遇到了一個問題,試圖做if-else語句來更新this.state.start的狀態。雖然它應該更新正確的值(if-else語句應該是正確的),但反應並不允許您像渲染一樣更新渲染函數中的狀態。如何有條件地設置this.state.start?下面的代碼:

class NormalHours extends React.Component { 
constructor(props) { 
    super(props) 
    this.state = { 
     start: null, 
    } 
} 
render() { 
    //Browser is very angry at this part 
    if(this.props.specStart == this.props.normStart || this.props.specStart == null) 
    { 
     //If special hours are null or equal to normal start use normal hours 
     this.setState({ 
      start: this.props.normStart; 
     }); 
    } 
    else 
    { 
     //Else the hours are different so use special hours 
     this.setState({ 
      start: this.props.specStart; 
     }); 
    } 
    return(
    <div> 
     //Using Material UI; this is rendered as a textbox 
     <TimePicker 
      name="StartTime" 
      onChange={(e, date) => { 
      this.props.onSetStartTime(Utils.convertDateToTimeString(date)) 
      }} 
      value={this.state.start} 
      /> 
+2

只是一個參考:你不應該在渲染狀態設置狀態,改變狀態觸發'render()',因此你將進入一個不幸的循環。除非您使用'shouldComponentUpdate'處理更新。 (你目前沒有) – Dan

+0

爲什麼normStart和specStart設置在道具上而不是狀態?如果他們在道具上,你可能可以使用shouldReceiveProps生命週期方法 – Pineda

+0

@Dan Yea這就是我遇到的問題,以及我想要如何解決的問題。我嘗試了多種方式,並且仍然存在循環問題。 – Jobokai

回答

1

可能您設置this.start.state像這樣的功能:

class NormalHours extends React.Component { 
    constructor(props) { 
     super(props) 
     this.state = { 
      start: null, 
     } 
     this.setStart(); 
    } 
    setStart =() => { 
    if(this.props.specStart == this.props.normStart || this.props.specStart == null) 
    { 
     //If special hours are null or equal to normal start use normal hours 
     this.setState({ 
      start: this.props.normStart; 
     }); 
    } 
    else 
    { 
     //Else the hours are different so use special hours 
     this.setState({ 
      start: this.props.specStart; 
     }); 
    } 
    } 
    render() { 
    return(
     <div> 
      //Using Material UI; this is rendered as a textbox 
      <TimePicker 
      name="StartTime" 
      onChange={(e, date) => { 
       this.props.onSetStartTime(Utils.convertDateToTimeString(date)) 
      }} 
      value={this.state.start} 
      /> 
     </div> 
    ) 
    } 
    } 

我不是太避讓是否調用構造方法被認爲是不好的做法,或者判斷

this.state = { 
    start: null 
} 

甚至在您立即修改狀態時也是必需的。

+0

我正在考慮嘗試在構造函數中運行一個方法,但不知道如何最好地接近它,我會嘗試你真正快速的。 – Jobokai

+0

您可以將其設置爲'this.props.specStart'並在'setStart()'中移除您的'else {}'塊,而不是在構造函數中初始化爲'null'。 – Dan

+0

這是一個很好的觀點。我認爲我遇到了一個JS錯誤,它不喜歡'start =()=>'非常確定我正在工作的環境(現在沒有控制權)。不過,我認爲你已經給了我正確的方向。 – Jobokai