В 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 вместо копирования данных в компоненты