[英]React setState inside componentDidUpdate causing infinite loop
[英]React setState in promise causing infinite loop
當fetchServices()
,調用api.getServices
,並在promise中調用this.setState
將fetchingServices
更改為false
。 然后隱藏加載微調器動畫。
由於某種原因,應用程序陷入無限循環:
constructor(props) {
super(props);
this.state = {
services: props.state.servicesReducer.services,
fetchingServices: true,
addingService: false
}
this.fetchServices = this.fetchServices.bind(this);
}
return (
<div className='services-container'>
<ul className='services-list'>
<li>
<AddServiceContainer />
</li>
{ this.state.fetchingServices
? <div className="icon-spin5 animate-spin"></div>
: null }
{ this.fetchServices() }
</ul>
</div>
)
fetchServices() {
console.log('fetchServices')
api.getServices(12345).then(res => {
console.log(' api.getServices res:', res)
this.setState({
fetchingServices: false
});
});
}
完整代碼
import React, { Component } from 'react'
import { connect } from 'react-redux'
import { AddServiceContainer } from './AddServiceContainer'
import { ServiceCard } from '../../components'
import { getServices } from '../../actions'
import * as api from '../../services/api'
export class ServicesContainer extends Component {
constructor(props) {
super(props);
this.state = {
services: props.state.servicesReducer.services,
fetchingServices: true,
addingService: false
}
this.fetchServices = this.fetchServices.bind(this);
}
onFormSubmit(e, user) {
e.preventDefault();
this.props.searchUser(user)
}
fetchServices() {
console.log('fetchServices')
api.getServices(12345).then(res => {
console.log(' api.getServices res:', res)
this.setState({
fetchingServices: false
});
});
}
render() {
return (
<div className='services-container'>
<ul className='services-list'>
<li>
<AddServiceContainer />
</li>
{ this.state.fetchingServices
? <div className="icon-spin5 animate-spin"></div>
: null }
{ this.fetchServices() }
</ul>
</div>
)
}
}
const mapStateToProps = (state) => {
return {
state
}
}
const mapDispatchToProps = (dispatch) => {
return {
getServices: (services) => { dispatch(getServices(services)) }
}
}
const ServicesListContainer = ServicesContainer;
export default connect(mapStateToProps, mapDispatchToProps)(ServicesListContainer)
每當執行setState時,都會再次調用render方法。 現在的問題是你在render方法中調用fetchServices()
方法。 現在每當fetchServices()
,它都會調用api。 當api的結果出現時,你使用setState
設置狀態,這會導致重新渲染(即再次調用你的render方法),再次調用fetchServices()
。 這就是它無限循環的原因。
解決方案:您應該在componentWillMount / componentDidMount方法中調用fetchServices()
,如下所示:
import React, { Component } from 'react'
import { connect } from 'react-redux'
import { AddServiceContainer } from './AddServiceContainer'
import { ServiceCard } from '../../components'
import { getServices } from '../../actions'
import * as api from '../../services/api'
export class ServicesContainer extends Component {
constructor(props) {
super(props);
this.state = {
services: props.state.servicesReducer.services,
fetchingServices: true,
addingService: false
}
this.fetchServices = this.fetchServices.bind(this);
}
componentWillMount(){
this.fetchServices();
}
onFormSubmit(e, user) {
e.preventDefault();
this.props.searchUser(user)
}
fetchServices() {
console.log('fetchServices')
api.getServices(12345).then(res => {
console.log(' api.getServices res:', res)
this.setState({
fetchingServices: false
});
});
}
render() {
return (
<div className='services-container'>
<ul className='services-list'>
<li>
<AddServiceContainer />
</li>
{ this.state.fetchingServices
? <div className="icon-spin5 animate-spin"></div>
: null }
</ul>
</div>
)
}
}
const mapStateToProps = (state) => {
return {
state
}
}
const mapDispatchToProps = (dispatch) => {
return {
getServices: (services) => { dispatch(getServices(services)) }
}
}
你永遠不應該在渲染功能中獲取數據。 您應該在componentDidMount函數中執行此操作。
在每個狀態或道具更改后調用render,如果在render函數中執行api調用,它將觸發setState並通過這樣做 - 一次又一次地渲染......
見鏈接
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.