javascript - React Action 请求和 Redux 结构

标签 javascript reactjs redux codesandbox

我已成功创建一个操作,向以下端点发出调用请求

https://api-football-v1.p.rapidapi.com/v2/statistics/{league_id}/{team_id}

API 文档是 here

我创建了一些demo在codesandbox中,你可以看到我可以在我的组件Stats.js中正确显示比赛winsdrawsloses > 对于圣保罗队(这是一个例子)

这里是我完成的所有步骤,我只向您展示实现它的相关代码

在我的 reducer 中,我创建了以下案例

  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>
    );
  }

它按预期工作,正如您在代码和框 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_HOMERECEIVE_TEAMS_STATS_WIN_AWAYRECEIVE_TEAMS_STATS_DRAW_HOMERECEIVE_TEAMS_STATS_DRAW_AWAYRECEIVE_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
      };
    //...
}

将单个更新分派(dispatch)到存储的好处是 Stats 组件渲染一次,而不是从 API 返回结果时渲染 6 次。

关于javascript - React Action 请求和 Redux 结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60635134/

相关文章:

javascript - knockout : get reference to component A to call one of A's function from component B?

javascript - 在 Jest 中测试 onbeforeunload

javascript - 普通函数和返回多个函数的函数之间的区别

javascript - jquery动态类名更新做图像延迟

javascript - 如何按多个条件筛选结果?

javascript - 显示在 A 帧中计算秒数的文本计时器

javascript - React Router 和 Flux(替代)

javascript - react.js 中的实例 v 状态变量

javascript - 类型错误 : Cannot read property 'actions' of undefined (React-Redux)

javascript - React, Redux - 使用 Redux 修改父组件