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

问题描述

我有一个父类组件,其状态(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;

因此,每当子组件中的新日期值发生变化时,每次我需要设置父状态时,我都会进行无限循环重新渲染。如何防止这种情况?

标签: reactjsantd

解决方案


总结一下我看到的一些评论,你应该this.datesGetChanged()从你的render函数中删除。如果必须在子状态更改时更新父状态,则在子状态更改时更新父状态。在您的代码中,这将是onChange您的日期选择器上的功能。

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

引用 React 文档:

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

渲染文档


推荐阅读