这是我的问题: 我获取一个API,操作如下:
const OPTIONS = {
method: 'GET',
headers: {
'X-RapidAPI-Host': 'api-football-v1.p.rapidapi.com',
'X-RapidAPI-Key': '44316d2130msh21fed66e06e6a24p1dd597jsnf2e92ca6ac85'
}
};
export function setLeagues() {
const countries =
[
{
france: ["Ligue 1", "Ligue 2"]
},
{
england: ["Premier League"]
},
{
germany: ["Bundesliga 1"]
}
];
let leagues = [];
countries.forEach((country) => {
fetch(`https://api-football-v1.p.rapidapi.com/v2/leagues/current/${Object.keys(country)[0]}`, OPTIONS)
.then(response => response.json())
.then((data) => {
Object.values(country)[0].forEach((league) => {
data.api.leagues.filter((league_api) => {
if(league_api.name === league) {
leagues.push(league_api);
}
});
});
});
});
return {
type: 'SET_LEAGUES',
payload: leagues
};
}
联赛返回正确的联赛对象数组。 这是减速器:
export default function(state, action) {
if (state === undefined) {
return [];
}
if (action.type === 'SET_LEAGUES') {
return action.payload;
} else {
return state;
}
}
最后是我的容器:
class LeaguesLabel extends Component {
componentDidMount() {
this.props.setLeagues()
}
render() {
console.log(this.props.leagues);
return(
<div>
<ul>
{
this.props.leagues.map((league) => {
return(
<li>
{league.name}
</li>
);
})
}
</ul>
</div>
);
}
}
function mapDispatchToProps(dispatch) {
return bindActionCreators(
{ setLeagues: setLeagues },
dispatch
);
}
function mapStateToProps(state) {
return {
leagues: state.leagues
}
}
export default connect(mapStateToProps, mapDispatchToProps)(LeaguesLabel);
我当然将setLeague导入到此容器中。
当我的console.log(this.props.leagues)显示一个包含“联盟”的对象的良好数组时,什么也没有显示。
预先感谢您的帮助!
答案 0 :(得分:0)
问题是您正在调用异步函数,并在其范围之外返回结果。
这是怎么回事,在收到API调用的答案之前先调用return语句。
因此,列表将为空...
您应该在https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
处了解异步功能。最重要的是,为了在redux动作中使用异步功能,您应该使用redux thunk。
这里很好的例子-> https://appdividend.com/2018/10/03/redux-thunk-tutorial-example/
答案 1 :(得分:0)
另一个答案是正确的,但要对此进行扩展,请考虑这样的功能
首先,它处理此块,然后遍历各个国家并开始执行提取请求:
countries.forEach((country) => {
fetch(`https://api-football-v1.p.rapidapi.com/v2/leagues/current/${Object.keys(country)[0]}`, OPTIONS)
.then(response => response.json())
.then((data) => {
Object.values(country)[0].forEach((league) => {
data.api.leagues.filter((league_api) => {
if(league_api.name === league) {
leagues.push(league_api);
}
});
});
});
});
接下来,在之前的工作有机会做任何事情之前,它将处理以下块:
return {
type: 'SET_LEAGUES',
payload: leagues
};
因此它已开始运行您的countries.forEach
,但获取承诺正在此函数之外解析,因此在将任何数据推入数组之前,您已经在返回它。
尝试使用await/async
语法,这样可以更轻松地处理破坏承诺的事情,例如:
export async function setLeagues() {
const countries = [
{
name: "france",
leagues: ["Ligue 1", "Ligue 2"],
},
{
name: "england",
leagues: ["Premier League"],
},
{
name: "germany",
leagues: ["Bundesliga 1"],
},
]
let payload = []
for (const country of countries) {
const { name, leagues } = country
const response = await fetch(
`https://api-football-v1.p.rapidapi.com/v2/leagues/current/${name}`,
OPTIONS
)
const data = await response.json()
for (const apiLeague of data.api.leagues) {
if (leagues.includes(apiLeague.name)) {
payload.push(apiLeague)
}
}
}
return {
type: "SET_LEAGUES",
payload,
}
}