更新状态时循环反应

时间:2020-04-17 19:11:29

标签: javascript reactjs

我有一个反应组件,负责使用fetch执行网络请求。 API响应将显示在组件内的卡上。

我已将响应状态的结构定义为movimientos。但是,当使用响应更新filtrarDatos函数内部的状态时,将创建无限循环,并无限执行fetch请求。

这是我的代码:

export class Datepicker extends Component {

   constructor(props) {
       super(props)
       this.state = {
           startDate: "",
           endDate: "",
           focusedInput: "",
           movimientos: {}
       }
   }

   filtrarDatos(startDateString, endDateString) {
       if (startDateString !== '' && endDateString !== '') {
           const empresa = {
               FECHA_INICIAL: startDateString,
               FECHA_FINAL: endDateString
           };

           const options = {
               method: 'POST',
               headers: { 'Content-Type': 'application/json' },
               body: JSON.stringify(empresa)

           }

           fetch('http://localhost:4000/api/movimiento/filtrarfecha', options)
               .then((res) => res.json())
               .then((data) => {
                   const { movimientos } = data
                   console.log({ movimientos })
                   this.setState({ movimientos })
               })
               .catch((err) => console.log(err))
       }
   }

   render() {
       const endDateString = this.state.endDate && this.state.endDate.format('YYYY-MM-DD') + "T13:47:14.985+00:00";
       const startDateString = this.state.startDate && this.state.startDate.format('YYYY-MM-DD') + "T13:47:14.985+00:00";

       return (
           <div className="DatePicker">
               <DateRangePicker
                   startDate={this.state.startDate} // momentPropTypes.momentObj or null,
                   endDate={this.state.endDate} // momentPropTypes.momentObj or null,
                   onDatesChange={({ startDate, endDate }) => this.setState({ startDate, endDate })} // PropTypes.func.isRequired,
                   focusedInput={this.state.focusedInput} // PropTypes.oneOf([START_DATE, END_DATE]) or null,
                   onFocusChange={focusedInput => this.setState({ focusedInput })} // PropTypes.func.isRequired,
                   endDatePlaceholderText={"Fecha inicial"}
                   startDatePlaceholderText={"Fecha final"}
                   displayFormat={"DD/MM/YYYY"}
                   numberOfMonths={1}
                   isOutsideRange={() => false}
                   showClearDates={true}
               />
               {this.filtrarDatos(startDateString, endDateString)}
           </div>
       )
   }
}

更清楚的是,该错误在代码的以下部分中,如果我对状态更新进行注释,则程序可以正常运行,并且仅发出单个请求。我是新来的反应者,我不知道发生了什么。

.then((data) => {
    const { movimientos } = data
    console.log({ movimientos })
    this.setState({ movimientos })
})

这是无限网络请求期间我的控制台的屏幕截图 console screenshot

2 个答案:

答案 0 :(得分:2)

您要在渲染主体中调用{this.filtrarDatos(startDateString, endDateString)},然后使用此方法更新状态,因此它会创建一个无限循环,因为当状态更改后,react会重新渲染组件。

答案 1 :(得分:2)

之所以会这样,是因为每次重新渲染(状态更改)后都会调用this.filtrarDatos,从而创建一个无限循环(更改数据,渲染,更改数据,重发...)

您可以将{ this.filtrarDatos(startDateString, endDateString) }移至componentDidMount

  1. 删除{ this.filtrarDatos(startDateString, endDateString) }
  2. lifecycle之后添加此constructor函数:
componentDidMount() {
  const endDateString = this.state.endDate && this.state.endDate.format('YYYY-MM-DD') + "T13:47:14.985+00:00";
  const startDateString = this.state.startDate && this.state.startDate.format('YYYY-MM-DD') + "T13:47:14.985+00:00";

  this.filtrarDatos(startDateString, endDateString);
}