完全获取数据后加载状态变化
loading status change after fetch data completely
我有动作创建者从 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)
});
}
};
和我的 Reducer:
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
并且如果将我的代码超时修复了我的错误:/
我该怎么办?
这里你的默认状态是错误的:
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)
不应在设置闪存卡之前调用。您的 reducer 和 action creator 是同步的(它们应该如此)。所以,那里没有什么值得注意的。
我看到您在 Constants.ADD_CARD
操作案例中使用了 action.data
,但在您的代码中您没有分派任何具有该类型的操作。你在别的地方做吗?也许这就是错误所在?
编辑:
您正在使用 .data
的另一个地方在您的渲染器中:this.props.cards.data
。 state.main
的值是多少?
你是如何创建你的 rootReducer 的?它应该是这样的:
const rootReducer = combineReducers({
main: FlashCard,
loading: Loading,
});
你在那里使用 main
吗?或者 cards
?
终于,我解决了我的问题:
在我的 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 reducer 更改为以下内容:
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;
}
};
我有动作创建者从 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)
});
}
};
和我的 Reducer:
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
并且如果将我的代码超时修复了我的错误:/
我该怎么办?
这里你的默认状态是错误的:
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)
不应在设置闪存卡之前调用。您的 reducer 和 action creator 是同步的(它们应该如此)。所以,那里没有什么值得注意的。
我看到您在 Constants.ADD_CARD
操作案例中使用了 action.data
,但在您的代码中您没有分派任何具有该类型的操作。你在别的地方做吗?也许这就是错误所在?
编辑:
您正在使用 .data
的另一个地方在您的渲染器中:this.props.cards.data
。 state.main
的值是多少?
你是如何创建你的 rootReducer 的?它应该是这样的:
const rootReducer = combineReducers({
main: FlashCard,
loading: Loading,
});
你在那里使用 main
吗?或者 cards
?
终于,我解决了我的问题:
在我的 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 reducer 更改为以下内容:
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;
}
};