我正在从API下载数据并写入state (posts)。
let res = await response.json();后的条件将在此函数之前执行。
他应该在什么时候执行this.setState({posts: res})?
目前,这是不适当的,因为:
render(),对象必须已经存在于state中state中定义一个空对象,因为它太复杂了功能:
async loadData()
{
try
{
this.setState({ loading: true});
let response = await fetch('http://localhost:5000/api/posts/', {
method: 'GET',
headers:
{
'Accept': 'application/json',
'Content-Type': 'application/json'
}
});
let res = await response.json();
if (response.status >= 200 && response.status < 300)
{
console.log(res);
this.setState({ posts: res});
this.setState({ loading: false});
}
else
{
let error = res;
throw error;
}
}
catch (error)
{
console.log('error' + error)
}
}发布于 2018-09-23 19:32:50
只要用承诺
loadData() {
this.setState({
loading: true
});
fetch('http://localhost:5000/api/posts/', {
method: 'GET',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
}
}).then(response => response.json()).then(res => {
this.setState({
posts: res
});
}).catch(reason => {
console.log('error ' + reason);
}).finally(() => {
this.setState({
loading: false
});
});
}发布于 2018-09-23 21:47:16
在当前的示例中,绝对没有理由使用async/await。我猜您相信,通过使用await,组件将只在完整的loadData函数完成时才呈现,但这是不正确的,因为async意味着将返回一个承诺。
您正在做的另一个假设是,只要您的数据尚未添加到您的状态中,您就不能render任何东西(您提到了调用呈现,但是这是通过自身反应来调用的,因此您不需要担心它,因为它是组件生命周期的一部分)
我创建了一个关于如何加载数据的小示例,基于您的代码,并有尽可能多的注释;)
const { Component } = React;
// only shows the breeds and potential subbreeds
const Breed = ({ name, subBreeds }) => {
return (
<div className="breed-item">
<span className="breed-title">{ name }</span>
{ subBreeds && subBreeds.map( (sub, i) => <Breed key={i} name={sub} /> ) }
</div>
);
};
class BreedContainer extends Component {
constructor() {
super();
// i'll be loading from the start
this.state = { loading: true };
}
componentDidMount() {
// flag to make sure I don't update my state when I am no longer mounted
this.mounted = true;
// get's called when my component will be added to the dom
fetch('https://dog.ceo/api/breeds/list/all')
// return the json
.then( response => response.json() )
// error occured with parsing the json, handle it
// through the console, and return an empty object
.catch( error => console.error( error ) || {} )
// set the state (in case still mounted)
.then( result => this.mounted && this.setState({
loading: false,
breeds: result.message
}) );
}
componentWillUnmount() {
// unmounted, make sure I do not update the state after that
this.mounted = false;
}
render() {
const { breeds, loading } = this.state;
// loading, so just display a loading message
if (loading) {
return <div>Loading please wait</div>;
}
// no breeds available, an error might have occured
// the user would have to check the console to make sure
// or you could save the error message instead
if (!breeds) {
return <div>No dog breeds found</div>;
}
// show all the retrieved breeds
return (
<div className="breed-container">
{ Object.keys( breeds ).map( (breed, i) => <Breed name={breed} subBreeds={breeds[breed]} key={i} /> ) }
</div>
);
}
}
const target = document.querySelector('#container');
ReactDOM.render( <BreedContainer />, target );.breed-item {
font-size: 0.95em;
padding: 5px;
}
.breed-item > .breed-item {
border-left: solid #a0a0a0 1px;
margin: 3px;
border-radius: 50%;
}
.breed-title {
text-transform: capitalize;
}<script id="react" src="https://cdnjs.cloudflare.com/ajax/libs/react/15.6.2/react.js"></script>
<script id="react-dom" src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/15.6.2/react-dom.js"></script>
<div id="container"></div>
https://stackoverflow.com/questions/52469460
复制相似问题