В React / Redux, как вызвать один и тот же выбор дважды в componentDidMount, установив 2 переменные состояния с результатами

Название является многословным, однако короткий / простой пример будет иметь большое значение для объяснения моего вопроса. У меня есть следующее начало компонента:

import React, { Component } from 'react';
import { connect } from 'react-redux';

import { fetchGames } from '../../path-to-action';

class TeamsApp extends Component {
    constructor(props) {
        super(props);
        this.state = {
            oldGames: [],
            newGames: []
        };
    }

    componentDidMount() {
        this.props.dispatch(fetchGames('1617'));
        this.setState({ oldGames: this.props.teamGameData });
        this.props.dispatch(fetchGames('1718'));
        this.setState({ newGames: this.props.teamGameData });
    }

    ...
    ...
}

function mapStateToProps(reduxState) {
    return {
        teamGameData: reduxState.GamesReducer.sportsData
    };
}

export default connect(mapStateToProps)(TeamsApp);

Я хотел бы действие / редуктор, который соответствует fetchGames() а также gamesReducer вызываться дважды, когда компонент монтируется. Это действие / редуктор собирает некоторые спортивные данные, и я пытаюсь получить данные за два отдельных сезона (сезон '1617' и сезон '1718'). fetchGames() построен правильно для обработки параметра сезона.

При текущей настройке состояния не устанавливаются, и мой линтер выдает ошибку Do not use setState in componentDidMount,

Могу ли я передать обратный вызов this.props.dispatch, который принимает результаты fetchGames() (команда teamGameData), и устанавливает состояния oldGames / newGames равными этому объекту?

Любая помощь с этим приветствуется!

Редактировать: если я просто удаляю this.setState(), то мой teamGameData проп просто переопределяется со вторым this.props.dispatch() вызов...

Редактировать 2: Я не уверен на 100%, если наилучшим подходом является наличие двух переменных состояния (oldGames, newGames). Мне просто нужно вызвать this.props.dispatch(fetchGames('seasonid')) дважды, когда загружается компонент, и получить результаты в виде двух отдельных объектов, которые может использовать остальная часть компонента.

Изменить 3: у меня есть следующая часть моего действия:

export const fetchSportsDataSuccess = (sportsData, season) => ({
    type: FETCH_NBA_TEAM_GAME_SUCCESS,
    payload: { sportsData, season }
});

и следующий случай в моем редукторе:

case FETCH_NBA_TEAM_GAME_SUCCESS:
console.log('payload', action.payload);
return {
    ...state,
    loading: false,
    sportsData: action.payload.sportsData
};

и console.log() теперь выглядит так:

payload
{ sportsData: Array(2624), season: "1718" }

но я не уверен, как использовать идентификатор сезона, чтобы создать ключ в возвращении с данными этого сезона....

Редактировать 4: найдено решение для редактирования 3 - Использовать переменную в качестве ключа объекта в редукторе - спасибо всем за помощь в этом, должны иметь возможность взять ее отсюда!

1 ответ

Решение

Копирование данных из избыточного хранилища в однокомпонентное состояние является анти-паттерном

Вместо этого вам следует изменить свое хранилище с избыточностью, например, используя объект для хранения данных, чтобы вы могли хранить данные за несколько сезонов:

sportsData: {
    '1617': { ... },
    '1718': { ... },
}

Таким образом, вы сможете выбрать оба сезона одновременно:

 componentDidMount() {
    const seasons = ['1718', '1617'];
    const promises = seasons.map(fetchGames);
    Promise.all(promises).catch(…);
}

И соедините их обоих:

// you can use props here too
const mapStateToProps = (reduxState, props) => ({
    // hardcoded like you did
    oldGames: reduxState.GamesReducer.sportsData['1617'],
    // or using some props value, why not
    newGames: reduxState.GamesReducer.sportsData[props.newSeason],
};

Или подключите магазин как обычно и зайдите за ключами:

const mapStateToProps = (reduxState, props) => ({
    games: reduxState.GamesReducer.sportsData,
};
…
render() {
  const oldGame = this.props.games[1718];
  const newGame = this.props.games[1718];
  …
}

Redux - единственный источник правды, всегда находите способ поместить все необходимое в Redux вместо копирования данных в компоненты

Другие вопросы по тегам