【问题标题】:Update this.state conditionally when rendering component in React?在 React 中渲染组件时有条件地更新 this.state?
【发布时间】:2017-04-05 15:17:25
【问题描述】:

我有一个时间选择器,我想将值设置为this.state.start。但是this.state.start 的值可能等于this.props.normalthis.props.spec,具体取决于用户是否设置了特殊时间,如果没有设置则返回使用正常时间。

我在尝试执行 if-else 语句来更新this.state.start 的状态时遇到了问题。虽然它应该正确更新值(if-else 语句应该是正确的),但 react 不允许您像我写的那样更新渲染函数中的状态。如何有条件地设置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}
          />

【问题讨论】:

  • 仅供参考:您不应该在渲染中设置状态,状态更改会触发render(),因此您将进入一个不幸的循环。除非您使用shouldComponentUpdate 处理更新。 (您目前没有)
  • 为什么 normStart 和 specStart 设置在 props 上而不是 state 上?如果它们在道具中,您可以使用 shouldReceiveProps 生命周期方法
  • @Dan Yea 这就是我遇到的问题,也是我试图弄清楚如何解决的问题。我尝试了多种方法,但循环仍然存在问题。
  • @pineda 我确实在我的本地代码中将它们设置为状态,希望将重点放在 This.State.Start 上。他们不会改变状态。
  • 我的意思是 componentWillReceiveProps :)

标签: javascript reactjs time


【解决方案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
}

甚至在您之后立即修改状态时也是必需的。

【讨论】:

  • 我正在考虑尝试在构造函数中运行一个方法,但不知道如何最好地接近它,我会尽快尝试你所拥有的。
  • 您可以将其设置为 this.props.specStart 并删除 setStart() 中的 else{} 块,而不是在构造函数中将 start 实例化为 null
  • 这是一个很好的观点。我想我遇到了一个 JS 错误,它不喜欢 start = () =&gt; 很确定它是我工作的环境(现在无法控制);但是我认为你给了我正确的方向。
  • 我现在收到此消息:只能更新已安装或已安装的组件。这通常意味着您在未安装的组件上调用了 setState()。这是一个无操作。请检查 NormalHours 组件的代码。
  • 建议对您的解决方案进行编辑,以将方法从构造函数移动到 componentDidMount(),这样该方法在组件安装后运行,而不是在启动时运行。还重新格式化了代码以远离 ES6 = () =&gt;,因为这在我的开发环境中不起作用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-06-07
  • 2018-12-20
  • 1970-01-01
  • 2021-02-21
  • 2015-05-16
  • 1970-01-01
  • 2019-05-29
相关资源
最近更新 更多