当您必须在Render()中设置状态时,如何避免无限的重新渲染循环?

时间:2019-04-09 21:36:56

标签: reactjs antd

我有一个父类组件,其状态(startDate和EndDate)由子组件设置。 子组件中有日期选择组件。有关父组件和子组件,请参见下面的代码:

父母

import React, { Component } from 'react';
import Child from './child-component'

class Parent extends Component {

state = {
  startDate: null,
  endDate: null,
}

startDSelected = (startD) => {
  this.setState({
    startDate: startD,
  })
}

endDSelected = (endD) => {
  this.setState({
    endDate: endD,
  })
}

  render() {
    return (
      <div>
        <Child selectedStartDate={startDSelected} selectedEndDate={endDSelected}>
      </div>
    );
  }

}

export default Parent;

孩子

import React, { Component } from 'react'

import { DatePicker } from "antd"

class Child extends Component {

  constructor(props) {
    super(props)
    this.state = {
      startValue: null,
      endValue: null,
      endOpen: false,
    }
  }

  onStartChange = (value) => {
    this.setState({
      startValue: value
    })
  }

  onEndChange = (value) => {
    this.setState({
      endValue: value
    })
  }

  handleStartOpenChange = (open) => {
    if (!open) {
      this.setState({ endOpen: true })
    }
  }

  handleEndOpenChange = (open) => {
    this.setState({ endOpen: open })
  }

  datesGetChanged = () => {
    const { startValue, endValue } = this.state
    this.props.selectedStartDate(startValue)
    this.props.selectedEndDate(endValue)
  }

  render() {
    const { startValue, endValue, endOpen } = this.state
    this.datesGetChanged()
    return (
      <div style={{ display: `inline-block` }}>
        <DatePicker
          format="YYYY-MM-DD"
          value={startValue}
          placeholder="Start"
          onChange={this.onStartChange}
          onOpenChange={this.handleStartOpenChange}\
          />
          <DatePicker
          format="YYYY-MM-DD"
          value={endValue}
          placeholder="End"
          onChange={this.onEndChange}
          open={endOpen}
          onOpenChange={this.handleEndOpenChange}
          />
      </div>
    )
  }

}

export default Child;

因此,每当子组件中的新日期值发生变化时,每次我需要设置父状态时,都会得到无限循环重新渲染。如何预防呢?

2 个答案:

答案 0 :(得分:2)

要总结一些见解,您应该从this.datesGetChanged()函数中删除render。如果在孩子的状态更改时必须更新父母的状态,则在孩子的状态更改时更新父母的状态。在您的代码中,这将是日期选择器上的onChange函数。

render是React按自己的时间表执行的事情,在其中调用状态更改函数是您描述的无限循环的秘诀。

引用React文档:

  

render()函数应该是纯函数,这意味着它不会修改组件状态,每次调用时都返回相同的结果,并且不与浏览器直接交互。

render docs

答案 1 :(得分:0)

componentDidUpdate(prevProps) {

this.datesGetChanged()

}