【发布时间】:2020-11-05 09:02:43
【问题描述】:
所以我是 React 的新手,我正在尝试将使用 axios 获取后的数据传递给组件:
index.js
class App extends React.Component {
state = { pokemon: null, errorMsg: '' };
componentDidMount() {
api
.get('', {
params: {
limit: 50,
offset: showrandom(),
},
})
.then((res) => {
const temporary = res.data.results;
const details = { pokemon: [] };
temporary.forEach((e) => {
api
.get('/' + e.name)
.then((res) => details.pokemon.push(res.data))
.catch((e) => console.log(e));
});
this.setState({ pokemon: details.pokemon });
})
.catch((e) => this.setState({ errorMsg: e }));
}
render() {
if (this.state.pokemon) {
return (
<React.Fragment>
<div
className="container-fluid"
style={{ textAlign: 'center', justifyContent: 'center', marginBottom: '5em' }}
>
<img alt="logo" src="logo" />
<p>by: Ihsan Fajar Ramadhan</p>
</div>
<div className="ui five column grid" style={{ padding: '2em' }}>
<Cards data={this.state.pokemon} />
</div>
</React.Fragment>
);
} else {
return (
<React.Fragment>
<div className="ui" style={{ textAlign: 'center', justifyContent: 'center', marginBottom: '5em' }}>
<img alt="logo" src="logo" />
<p>by: Ihsan Fajar Ramadhan</p>
</div>
<div className="ui" style={{ textAlign: 'center', justifyContent: 'center' }}>
<i className="compass loading icon massive blue"></i>
<p className="ui text blue">Loading...</p>
</div>
</React.Fragment>
);
}
}
}
Card.js
import React from 'react';
const Card = (props) => {
let pokemon = props.data.map((pokemon, i) => {
return (
<div className="column" key={i}>
<div className="ui fluid card">
<a className="image" href="/">
<img alt="nama" src={pokemon.sprites.front_default} />
</a>
<div className="content" style={{ textAlign: 'center' }}>
<a className="header" href="/">
{pokemon.species.name}{' '}
</a>
</div>
</div>
</div>
);
});
if (props.data.length > 0) {
return <>{pokemon}</>;
} else {
return <>fetching</>;
}
};
export default Card;
加载屏幕渲染成功,在pokemon状态更新后,它通过if(this.state.pokemon)这意味着状态已更新的条件,然后它尝试用组件渲染元素。但问题是组件的数据道具尚未传递,它呈现“获取”而不是{pokemon}。我一直在寻找解决方案,但我被困住了。奇怪的是,当我更改内容(添加或删除单词)时,数据会传递给组件。
【问题讨论】:
-
您是否在 Card.js 组件中登录了
props.data?它的结构是否正确,你能很好地看到日志吗? -
我很确定您所描述的情况是
this.state.pokemon是一个空数组。[]是真实的,但它的长度是0,这是导致fetching被渲染的确切条件。你能显示你加载数据并调用 setState 的部分吗? -
我已经更新了这段代码,并且我已经 cosoled this.state.pokemon 它返回了口袋妖怪列表,Card.js 中的 console.log 的结果也返回了相同的数据。 this.state.pokemon 的初始值为 null,所以当它更新时应该渲染
元素。 -
问题是:
forEach循环不会等待内部的异步代码,只有 for 循环会,而且您甚至没有使用过await。当您调用this.setState({ pokemon: details.pokemon });时,所有的api 调用都还没有完成,它仍然是[],这正是导致您观察到的行为的原因。 -
为了解决这个问题,你也可以使用
Promise.all()并行运行所有请求,然后在.then回调中调用setState。进行调试的一种非常简单的方法是插入<pre>{JSON.stringify(this.state)}</pre>,这样您将看到this.state的实际内容,而不是可能无法反映其中实际内容的console.log 输出。
标签: javascript reactjs axios