您好我有以下组件
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import RecipeItems from './RecipeItems';
class RecipeContainer extends Component {
constructor() {
super();
this.state = {
};
}
loadRecipe()
{
fetch("http://localhost:64755/Api/recipe/" + this.props.recipeId)
.then(result => {
return result.json();
})
.then(data => {
//const foo = data;
this.setState({ Recipe: data })
}
)
.catch(e => {
console.log(e)
return e;
});
}
render() {
this.loadRecipe()
console.log('in recipecontainer');
return(<div></div>)
}
}
RecipeContainer.propTypes = {
recipeId: PropTypes.number
};
export default RecipeContainer;
我最初把一个console.log()用于调试,但后来我注意到这个方法正在调用它似乎是一个循环。它不会停止。这有什么不对?我知道当我删除this.setState({Recipe:data})时,循环就会停止。
答案 0 :(得分:1)
您正在使用fetch
方法进行render
来电。此调用使用state
更新组件的this.setstate
,这会触发对render
的调用,依此类推。这就是你在循环中看到console.log
语句的原因。
您应该在fetch
生命周期方法中componentDidMount
数据来阻止此类无限循环。只有在componentDidMount
第一次完成运行后才会调用render
,并且无法进行无限循环的调用。
来自docs:
安装组件后立即调用
componentDidMount()
。需要DOM节点的初始化应该放在这里。如果需要从远程端点加载数据,这是实例化网络请求的好地方。
代码:
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import RecipeItems from './RecipeItems';
class RecipeContainer extends Component {
constructor() {
super();
this.state = {
Recipe: null
};
}
componentDidMount(){
fetch("http://localhost:64755/Api/recipe/" + this.props.recipeId)
.then(result => {
return result.json();
})
.then(data => {
this.setState({ Recipe: data });
})
.catch(e => {
console.log(e);
return e;
});
}
render() {
console.log('in recipecontainer');
return(<div></div>);
}
}
RecipeContainer.propTypes = {
recipeId: PropTypes.number
};
export default RecipeContainer;
答案 1 :(得分:0)
除了在渲染函数中渲染HTML代码之外,你不应该运行任何东西。因此,将this.loadRecipe
移动到componentDidMount函数,看看是否有帮助。
这里也是你的ajax调用的正确语法:
fetch("http://localhost:64755/Api/recipe/" + this.props.recipeId)
.then(result => {
this.setState({ Recipe: result.json() })
})
.catch(e => {
console.log(e);
});
你也可以在你的班级中设置defultProps,如下所示:
class RecipeContainer extends Component {
static defaultProps = {
...defaultprops
}
constructor() {
super();
this.state = {
};
}
}
答案 2 :(得分:0)
它是一个循环。只要道具或状态发生变化,就会调用render方法。在你的情况下,你正在调用loadRecipe()。更新状态。导致重新执行渲染,再次调用loadRecipe()。所以这将是一个无限循环。你可以在某些生命周期方法中调用loadRecipe。比较componentDidMount()。
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import RecipeItems from './RecipeItems';
class RecipeContainer extends Component {
constructor() {
super();
this.state = {
};
}
componentDidMount(){
this.loadRecipe() // will be called only once.
// thus the state will be updated once by this function.
}
loadRecipe()
{
fetch("http://localhost:64755/Api/recipe/" + this.props.recipeId)
.then(result => {
return result.json();
})
.then(data => {
//const foo = data;
this.setState({ Recipe: data })
}
)
.catch(e => {
console.log(e)
return e;
});
}
render() {
console.log('in recipecontainer');
return(<div></div>)
}
}
RecipeContainer.propTypes = {
recipeId: PropTypes.number
};
export default RecipeContainer;