React Action Requests и Redux Structure

Я успешно создал действие, выполняющее запрос вызова на следующую конечную точку

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

Документация по API находится здесь

Я создал небольшую демонстрацию вcodeandbox, где вы можете видеть, что я могу отображать совпадения wins , draws и loses правильно в моем компоненте Stats.js для команды Сан-Паулу (это пример)

Здесь все шаги, которые я сделал, я покажу вам только соответствующий код для его достижения

В своих редукторах я создал следующие кейсы

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

Он работает так, как ожидалось, как вы можете видеть в демонстрации в коде и коробке, но я не знаю если я все делаю правильно с состояниями Redux, вызовите действие и компонент.

У меня вопрос, это правда? Могу я сделать это лучше? Если да, как мне провести рефакторинг?

Любые изменения кода и рефакторинга в демонстрации кода и кода позволяют принять ответ.


person Koala7    schedule 11.03.2020    source источник
comment
Если код работает так, как задумано, я бы рекомендовал спросить в Code Review SE.   -  person cbr    schedule 19.03.2020


Ответы (1)


Отправьте одно действие, чтобы обновить хранилище для результата, вместо отправки нескольких действий для каждого поля в результате.

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 / redurs / 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.

person Oluwafemi Sule    schedule 15.03.2020
comment
Не могли бы вы обновить демоверсию в codeandbox, чтобы принять ответ? Мне также нужно каждое состояние в моем компоненте статистики. - person Koala7; 15.03.2020
comment
Компонент Stats не требует никаких изменений. Единственные файлы, которые нужно обновить, - это src/actions/index.js и src/reducers/index.js. - person Oluwafemi Sule; 17.03.2020