React Action 请求和 Redux 结构
React Action Requests and Redux Structure
我已经成功地创建了一个向以下端点发出调用请求的操作
https://api-football-v1.p.rapidapi.com/v2/statistics/{league_id}/{team_id}
API 文档是 here
我在 codesandbox 中创建了一些 demo,您可以看到我可以在我的组件 [=19] 中正确显示匹配项 wins
、draws
和 loses
=] 圣保罗队(这是一个例子)
这里是我完成的所有步骤,我只向您展示实现它的相关代码
在我的减速器中,我创建了以下案例
RECEIVE_TEAMS_STATS_WIN_HOME,
RECEIVE_TEAMS_STATS_WIN_AWAY,
RECEIVE_TEAMS_STATS_DRAW_HOME,
RECEIVE_TEAMS_STATS_DRAW_AWAY,
RECEIVE_TEAMS_STATS_LOSE_HOME,
RECEIVE_TEAMS_STATS_LOSE_AWAY
在我的初始状态下我有
teamsStatsWinHome: [],
teamsStatsWinAway: [],
teamsStatsDrawHome: [],
teamsStatsDrawAway: [],
teamsStatsLoseHome: [],
teamsStatsLoseAway: [],
这些是我的案例
case RECEIVE_TEAMS_STATS_WIN_HOME:
return {
...state,
teamsStatsWinHome: action.json,
isTeamsStatsLoading: false
};
case RECEIVE_TEAMS_STATS_WIN_AWAY:
return {
...state,
teamsStatsWinAway: action.json,
isTeamsStatsLoading: false
};
case RECEIVE_TEAMS_STATS_DRAW_HOME:
return {
...state,
teamsStatsDrawHome: action.json,
isTeamsStatsLoading: false
};
case RECEIVE_TEAMS_STATS_DRAW_AWAY:
return {
...state,
teamsStatsDrawAway: action.json,
isTeamsStatsLoading: false
};
case RECEIVE_TEAMS_STATS_LOSE_HOME:
return {
...state,
teamsStatsLoseHome: action.json,
isTeamsStatsLoading: false
};
case RECEIVE_TEAMS_STATS_LOSE_AWAY:
return {
...state,
teamsStatsLoseAway: action.json,
isTeamsStatsLoading: false
};
这是我对 API 端点
的调用请求的操作
export function getTeamsStats(league, team) {
return function(dispatch) {
return axios
.get(
`https://www.api-football.com/demo/api/v2/statistics/${league}/${team}`
)
.then(res => {
let homewins = res.data.api.statistics.matchs.wins.home;
dispatch(receivedTeamsStatWinHome(homewins));
let awaywins = res.data.api.statistics.matchs.wins.away;
dispatch(receivedTeamsStatWinAway(awaywins));
let drawhome = res.data.api.statistics.matchs.draws.home;
dispatch(receivedTeamsStatDrawHome(drawhome));
let drawaway = res.data.api.statistics.matchs.draws.away;
dispatch(receivedTeamsStatDrawAway(drawaway));
let losehome = res.data.api.statistics.matchs.loses.home;
dispatch(receivedTeamsStatLoseHome(losehome));
let loseaway = res.data.api.statistics.matchs.loses.away;
dispatch(receivedTeamsStatLoseAway(loseaway));
})
.catch(e => {
console.log(e);
});
};
然后将函数 getTeamsStats
放入 fetchLeaguesList
以获取圣保罗结果作为示例
这是我组件中的相关代码Stats.js
let Stats = ({
teamsStatsWinHome,
teamsStatsWinAway,
teamsStatsDrawHome,
teamsStatsDrawAway,
teamsStatsLoseHome,
teamsStatsLoseAway,
loading
}) => {
let stats = "";
if (
teamsStatsWinHome &&
teamsStatsWinAway &&
teamsStatsDrawHome &&
teamsStatsDrawAway &&
teamsStatsLoseHome &&
teamsStatsLoseAway
) {
stats = (
<div className="col-sm-6">
<div className="card detail-card border-0 rounded-0 bg-transparent">
<div className="card-body text-decoration-none text-secondary">
{JSON.stringify(teamsStatsWinHome)}
{JSON.stringify(teamsStatsWinAway)}
{JSON.stringify(teamsStatsDrawHome)}
{JSON.stringify(teamsStatsDrawAway)}
{JSON.stringify(teamsStatsLoseHome)}
{JSON.stringify(teamsStatsLoseAway)}
</div>
</div>
</div>
);
}
它按预期工作,正如您在 codesandbox 中看到的那样 demo 但我不知道我是否以正确的方式处理 Redux 状态、调用操作和组件。
我的问题是,这样对吗?我可以让它变得更好吗?如果是,我应该如何重构?
codesandbox中的任何重构和代码更改demo都很好接受答案
分派单个操作来更新结果的存储,而不是为结果中的每个字段分派多个操作。
src/actions/index.js
export const RECEIVE_TEAMS_STATS = "RECEIVE_TEAMS_STATS";
export const receivedTeamsStat = json => ({
type: RECEIVE_TEAMS_STATS,
json: json
});
export function getTeamsStats(league, team) {
return function(dispatch) {
return axios
.get(
`https://www.api-football.com/demo/api/v2/statistics/${league}/${team}`
)
.then(res => {
const {
wins: { home: teamsStatsWinHome, away: teamsStatsWinAway },
draws: { home: teamsStatsDrawHome, away: teamsStatsDrawAway },
loses: { home: teamsStatsLoseHome, away: teamsStatsLoseAway }
} = res.data.api.statistics.matchs;
const teamStats = {
teamsStatsWinHome,
teamsStatsWinAway,
teamsStatsDrawHome,
teamsStatsDrawAway,
teamsStatsLoseHome,
teamsStatsLoseAway
}
dispatch(receivedTeamsStat(teamStats));
})
.catch(e => {
console.log(e);
});
};
所有 6 个动作(RECEIVE_TEAMS_STATS_WIN_HOME
、RECEIVE_TEAMS_STATS_WIN_AWAY
、RECEIVE_TEAMS_STATS_DRAW_HOME
、RECEIVE_TEAMS_STATS_DRAW_AWAY
、RECEIVE_TEAMS_STATS_LOSE_HOME
、RECEIVE_TEAMS_STATS_LOSE_AWAY
)都可以卷入一个RECEIVE_TEAMS_STATS
动作及处理如下:
src/reducers/index.js
import {
//..
RECEIVE_TEAMS_STATS
} from "../actions";
const reducer = (state = initialState, action) => {
switch (action.type) {
//...
case RECEIVE_TEAMS_STATS:
return {
...state,
...action.json,
isTeamsStatsLoading: false
};
//...
}
将单个更新分派到商店的好处是 Stats
组件呈现一次,而不是在 API.
结果 return 时呈现 6 次
我已经成功地创建了一个向以下端点发出调用请求的操作
https://api-football-v1.p.rapidapi.com/v2/statistics/{league_id}/{team_id}
API 文档是 here
我在 codesandbox 中创建了一些 demo,您可以看到我可以在我的组件 [=19] 中正确显示匹配项 wins
、draws
和 loses
=] 圣保罗队(这是一个例子)
这里是我完成的所有步骤,我只向您展示实现它的相关代码
在我的减速器中,我创建了以下案例
RECEIVE_TEAMS_STATS_WIN_HOME,
RECEIVE_TEAMS_STATS_WIN_AWAY,
RECEIVE_TEAMS_STATS_DRAW_HOME,
RECEIVE_TEAMS_STATS_DRAW_AWAY,
RECEIVE_TEAMS_STATS_LOSE_HOME,
RECEIVE_TEAMS_STATS_LOSE_AWAY
在我的初始状态下我有
teamsStatsWinHome: [],
teamsStatsWinAway: [],
teamsStatsDrawHome: [],
teamsStatsDrawAway: [],
teamsStatsLoseHome: [],
teamsStatsLoseAway: [],
这些是我的案例
case RECEIVE_TEAMS_STATS_WIN_HOME:
return {
...state,
teamsStatsWinHome: action.json,
isTeamsStatsLoading: false
};
case RECEIVE_TEAMS_STATS_WIN_AWAY:
return {
...state,
teamsStatsWinAway: action.json,
isTeamsStatsLoading: false
};
case RECEIVE_TEAMS_STATS_DRAW_HOME:
return {
...state,
teamsStatsDrawHome: action.json,
isTeamsStatsLoading: false
};
case RECEIVE_TEAMS_STATS_DRAW_AWAY:
return {
...state,
teamsStatsDrawAway: action.json,
isTeamsStatsLoading: false
};
case RECEIVE_TEAMS_STATS_LOSE_HOME:
return {
...state,
teamsStatsLoseHome: action.json,
isTeamsStatsLoading: false
};
case RECEIVE_TEAMS_STATS_LOSE_AWAY:
return {
...state,
teamsStatsLoseAway: action.json,
isTeamsStatsLoading: false
};
这是我对 API 端点
的调用请求的操作export function getTeamsStats(league, team) {
return function(dispatch) {
return axios
.get(
`https://www.api-football.com/demo/api/v2/statistics/${league}/${team}`
)
.then(res => {
let homewins = res.data.api.statistics.matchs.wins.home;
dispatch(receivedTeamsStatWinHome(homewins));
let awaywins = res.data.api.statistics.matchs.wins.away;
dispatch(receivedTeamsStatWinAway(awaywins));
let drawhome = res.data.api.statistics.matchs.draws.home;
dispatch(receivedTeamsStatDrawHome(drawhome));
let drawaway = res.data.api.statistics.matchs.draws.away;
dispatch(receivedTeamsStatDrawAway(drawaway));
let losehome = res.data.api.statistics.matchs.loses.home;
dispatch(receivedTeamsStatLoseHome(losehome));
let loseaway = res.data.api.statistics.matchs.loses.away;
dispatch(receivedTeamsStatLoseAway(loseaway));
})
.catch(e => {
console.log(e);
});
};
然后将函数 getTeamsStats
放入 fetchLeaguesList
以获取圣保罗结果作为示例
这是我组件中的相关代码Stats.js
let Stats = ({
teamsStatsWinHome,
teamsStatsWinAway,
teamsStatsDrawHome,
teamsStatsDrawAway,
teamsStatsLoseHome,
teamsStatsLoseAway,
loading
}) => {
let stats = "";
if (
teamsStatsWinHome &&
teamsStatsWinAway &&
teamsStatsDrawHome &&
teamsStatsDrawAway &&
teamsStatsLoseHome &&
teamsStatsLoseAway
) {
stats = (
<div className="col-sm-6">
<div className="card detail-card border-0 rounded-0 bg-transparent">
<div className="card-body text-decoration-none text-secondary">
{JSON.stringify(teamsStatsWinHome)}
{JSON.stringify(teamsStatsWinAway)}
{JSON.stringify(teamsStatsDrawHome)}
{JSON.stringify(teamsStatsDrawAway)}
{JSON.stringify(teamsStatsLoseHome)}
{JSON.stringify(teamsStatsLoseAway)}
</div>
</div>
</div>
);
}
它按预期工作,正如您在 codesandbox 中看到的那样 demo 但我不知道我是否以正确的方式处理 Redux 状态、调用操作和组件。
我的问题是,这样对吗?我可以让它变得更好吗?如果是,我应该如何重构?
codesandbox中的任何重构和代码更改demo都很好接受答案
分派单个操作来更新结果的存储,而不是为结果中的每个字段分派多个操作。
src/actions/index.js
export const RECEIVE_TEAMS_STATS = "RECEIVE_TEAMS_STATS";
export const receivedTeamsStat = json => ({
type: RECEIVE_TEAMS_STATS,
json: json
});
export function getTeamsStats(league, team) {
return function(dispatch) {
return axios
.get(
`https://www.api-football.com/demo/api/v2/statistics/${league}/${team}`
)
.then(res => {
const {
wins: { home: teamsStatsWinHome, away: teamsStatsWinAway },
draws: { home: teamsStatsDrawHome, away: teamsStatsDrawAway },
loses: { home: teamsStatsLoseHome, away: teamsStatsLoseAway }
} = res.data.api.statistics.matchs;
const teamStats = {
teamsStatsWinHome,
teamsStatsWinAway,
teamsStatsDrawHome,
teamsStatsDrawAway,
teamsStatsLoseHome,
teamsStatsLoseAway
}
dispatch(receivedTeamsStat(teamStats));
})
.catch(e => {
console.log(e);
});
};
所有 6 个动作(RECEIVE_TEAMS_STATS_WIN_HOME
、RECEIVE_TEAMS_STATS_WIN_AWAY
、RECEIVE_TEAMS_STATS_DRAW_HOME
、RECEIVE_TEAMS_STATS_DRAW_AWAY
、RECEIVE_TEAMS_STATS_LOSE_HOME
、RECEIVE_TEAMS_STATS_LOSE_AWAY
)都可以卷入一个RECEIVE_TEAMS_STATS
动作及处理如下:
src/reducers/index.js
import {
//..
RECEIVE_TEAMS_STATS
} from "../actions";
const reducer = (state = initialState, action) => {
switch (action.type) {
//...
case RECEIVE_TEAMS_STATS:
return {
...state,
...action.json,
isTeamsStatsLoading: false
};
//...
}
将单个更新分派到商店的好处是 Stats
组件呈现一次,而不是在 API.