//action.js
export const FETCH_PLAYERS_SUCCESS = 'FETCH_PLAYERS_SUCCESS';
export const fetchPlayersSuccess = players => ({
type: FETCH_PLAYERS_SUCCESS,
players
});
export const SET_WR = 'SET_WR';
export const setWR = wr => ({
type: SET_WR,
wr
});
export const SET_QB = 'SET_QB';
export const setQB = qb => ({
type: SET_QB,
qb
});
export const SET_RB = 'SET_RB';
export const setRB = rb => ({
type: SET_RB,
rb
});
export const SET_TE = 'SET_TE';
export const setTE = te => ({
type: SET_TE,
te
});
export const fetchPlayers = () => {
return dispatch => {
const proxyurl = "https://cors-anywhere.herokuapp.com/";
const url = "http://api.fantasy.nfl.com/v1/players/stats?statType=seasonStats&season=2017&week=1&format=json"; // site that doesn’t send Access-Control-*
fetch(proxyurl + url)
.then(res => res.json())
.catch(error => {
console.error('Error:', error)
dispatch(fetchPlayersError(error))
})
.then(response => {
let thisPlayer = response.players
for(let i=0; i<thisPlayer.length; i++){
if(thisPlayer[i].position == 'WR'){
dispatch(setWR(thisPlayer[i]))
}
if(thisPlayer[i].position == 'QB'){
dispatch(setQB(thisPlayer[i]))
}
if(thisPlayer[i].position == 'RB'){
dispatch(setRB(thisPlayer[i]))
}
if(thisPlayer[i].position == 'TE'){
dispatch(setTE(thisPlayer[i]))
}
}
dispatch(fetchPlayersSuccess(response))
});
}}
我的减速机:
//reducer.js
const initialState = {
players: [],
loading: false,
error: null,
wr: [],
qb: [],
rb: [],
te: []
};
export default (state = initialState, action) => {
if (action.type === FETCH_PLAYERS_REQUEST) {
return Object.assign({}, state, {
loading: true,
error: null
});
}
if (action.type === FETCH_PLAYERS_SUCCESS) {
//console.log(state, action);
return Object.assign({}, state, {
players: action.players,
loading: false
});
}
if (action.type === SET_QB) {
//console.log(state, action);
return Object.assign({}, state, {
qb: action.qb,
loading: false
});
}
if (action.type === SET_RB) {
//console.log(state, action);
return Object.assign({}, state, {
rb: action.rb,
loading: false
});
}
if (action.type === SET_WR) {
//console.log(state, action);
return Object.assign({}, state, {
wr: action.wr,
loading: false
});
}
if (action.type === SET_TE) {
//console.log(state, action);
return Object.assign({}, state, {
te: action.te,
loading: false
});
}
if (action.type === FETCH_PLAYERS_ERROR) {
return Object.assign({}, state, {
loading: false,
error: action.error
});
}
return state;
};
感谢您提前提供任何帮助。
答案 0 :(得分:2)
我认为你正在覆盖状态对象。 我认为你的代码不会添加到数组中,只是覆盖它。
另外,我会将响应中的数组传递给一个调度函数,而不是在调用dispatch之前循环调用serval调度函数或格式化对象。我认为调试和维护会更容易。您只需要拨打一次电话,除非您有令人信服的理由多次拨打电话。
为reducer使用switch语句并仅在需要时更新每个数组,否则只保持数组不在当前状态。
我看到你正在使用Object.assign
。相反,请尝试根据需要单独更新数组,并为每个操作返回一个新对象。
我不知道您的所有要求,但这可能会有所帮助:
export const loadPlayers = formattedRespObj => ({
type: 'FETCH_PLAYERS_SUCCESS',
players: formattedRespObj.players,
wr: formattedRespObj.wr,
qb: formattedRespObj.qb,
rb: formattedRespObj.rb,
te: formattedRespObj.te
});
function formatRespObj(playersResp) {
let formattedRespObj = {players: [], wr: [], qb: [], rb: [], te: []};
// Note, this can probably be prettier
for (let i = 0; i < playersResp.length; i++) {
switch (playersResp[i].position) {
case 'WR':
formattedRespObj.wr.push(playersResp[i]);
break;
case 'QB':
formattedRespObj.qb.push(playersResp[i]);
break;
case 'RB':
formattedRespObj.rb.push(playersResp[i]);
break;
case 'TE':
formattedRespObj.te.push(playersResp[i]);
break;
default:
console.error("Unknown player position");
break;
}
}
formattedRespObj.players = [...formattedRespObj.wr, ...formattedRespObj.qb, ...formattedRespObj.rb, ...formattedRespObj.te];
return formattedRespObj;
}
const initialState = {
players: [],
loading: false,
error: null,
wr: [],
qb: [],
rb: [],
te: []
};
export default function reducer(playersState = initialState, action) {
switch (action.type) {
case 'LOAD_PLAYERS':
return {
players: [...playersState.wr, playersState.wr],
loading: true,
error: null,
wr: [...playersState.wr, action.wr],
qb: [...playersState.qb, action.qb],
rb: [...playersState.rb, action.rb],
te: [...playersState.te, action.te],
};
case 'FETCH_PLAYERS_ERROR':
return {
loading: false,
error: action.error,
wr: playersState.wr,
qb: playersState.qb,
rb: playersState.rb,
te: playersState.te
};
default:
return {
loading: false,
error: null,
wr: playersState.wr,
qb: playersState.qb,
rb: playersState.rb,
te: playersState.te
}
}
}
export const fetchPlayers = () => {
return dispatch => {
const proxyurl = "https://cors-anywhere.herokuapp.com/";
const url = "http://api.fantasy.nfl.com/v1/players/stats?statType=seasonStats&season=2017&week=1&format=json"; // site that doesn’t send Access-Control-*
fetch(proxyurl + url)
.then(res => res.json())
.catch(error => {
console.error('Error:', error);
dispatch(fetchPlayersError(error));
})
.then(response => {
let formattedRespObj = formatRespObj(response);
dispatch(loadPlayers(formattedRespObj));
dispatch(fetchPlayersSuccess(response))
});
}
};