我有动作创建者从API获取数据,并有另一个动作创建者用于加载状态,并希望在完全获取数据时更改加载状态。
现在,我编写了以下代码但效果不佳,在完全提取数据之前将状态更改为false。
我的ActionCreator:
export const loadingStatus = (bool) => {
return {
type: Constants.LOADING_STATUS,
isLoading: bool
};
}
const allFlashCards = (action) => {
return{
type: Constants.ALL_CARD,
...action
}
};
export const fetchAllFlashCards = () => {
return (dispatch) => {
dispatch(loadingStatus(true));
return axios.post(API.DISPLAY_ALL_CARDS)
.then((data)=>{
console.warn(data);
dispatch(allFlashCards(data));
dispatch(loadingStatus(false));
}).catch((error)=>{
console.warn(error)
});
}
};
和我的减速机:
const FlashCard = (state = [], action) => {
switch (action.type) {
case Constants.ADD_CARD:
return {...state, data: action.data};
break;
case Constants.ALL_CARD:
return {...state, data: action};
break;
default:
return state;
}
};
export const Loading = (status= false, action) => {
switch (action.type) {
case Constants.LOADING_STATUS:
return action.isLoading;
break;
default:
return status;
}
}
在我的组件中:
componentDidMount() {
this.props.fetchCards();
}
render() {
return(
<div>
{this.props.loading ?
<Loading/> :
Object.keys(this.props.cards.data).map(this.renderCard)
}
</div>
);
}
const mapStateToProps = (state) => ({
cards: state.main,
loading: state.loading
});
const mapDispatchToProps = (dispatch) => ({
fetchCards: bindActionCreators(fetchAllFlashCards, dispatch)
});
和combineReducer是:
import { combineReducers } from 'redux';
import FlashCard , { Loading } from './FlashCard.js';
import { routerReducer } from "react-router-redux";
export default combineReducers({
main: FlashCard,
loading: Loading,
routing: routerReducer
});
在我的页面中,我在控制台中出错,它是:
Uncaught TypeError: Cannot read property 'data' of undefined
如果我的代码在超时时修复我的错误:/
我该怎么办?
答案 0 :(得分:1)
您的默认状态是错误的:
const FlashCard = (state = [], action) => {
switch (action.type) {
case Constants.ADD_CARD:
return {...state, data: action.data};
break;
case Constants.ALL_CARD:
return {...state, data: action};
break;
default:
return state;
}
};
它应该是一个空对象{}
而不是一个空数组[]
,因为你要返回对象。
此代码
export const fetchAllFlashCards = () => {
return (dispatch) => {
dispatch(loadingStatus(true));
return axios.post(API.DISPLAY_ALL_CARDS)
.then((data)=>{
console.warn(data);
dispatch(allFlashCards(data));
dispatch(loadingStatus(false));
}).catch((error)=>{
console.warn(error)
});
}
};
看起来完全没问题。在设置闪存卡之前,不应调用loadingStatus(false)
。您的减速器和动作创建器是同步的(应该如此)。所以,没有什么值得注意的。
我看到您在action.data
操作案例中使用Constants.ADD_CARD
,但在您的代码中,您不会发送任何具有该类型的操作。你在其他地方做到了吗?也许错误在哪里?
编辑:
您使用.data
的另一个地方是您的渲染器:this.props.cards.data
。 state.main
的价值是什么?
你是如何创建rootReducer的?它应该是这样的:
const rootReducer = combineReducers({
main: FlashCard,
loading: Loading,
});
你在那里使用main
吗?或者也许是cards
?
答案 1 :(得分:0)
最后,我解决了我的问题:
在我的actionCreator中,将fetchAllFlashCards方法更改为以下内容:
export const fetchAllFlashCards = () => {
return (dispatch) => {
dispatch(loadingStatus(true));
return axios.post(API.DISPLAY_ALL_CARDS)
.then(({data})=>{
dispatch(allFlashCards(data));
dispatch(loadingStatus(false));
}).catch((error)=>{
console.warn(error)
});
}
};
并在reducer中将FlashCard减速器更改为以下内容:
const FlashCard = (state = [], action) => {
switch (action.type) {
case Constants.ADD_CARD:
return {...state, data: action.data};
break;
case Constants.ALL_CARD:
return {...state, data: action.data};
break;
default:
return state;
}
};