2017-04-05 101 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