【问题标题】:loading status change after fetch data completely完全获取数据后加载状态变化
【发布时间】:2018-01-24 20:20:26
【问题描述】:

我有动作创建者从 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 如果我的代码超时修复了我的错误:/

我该怎么办?

【问题讨论】:

  • 什么是 state.main?
  • combineReducer 添加到我的问题中

标签: javascript reactjs redux react-redux redux-thunk


【解决方案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)。你的 reducer 和 action creators 是同步的(它们应该是同步的)。所以,没有什么值得注意的。

我看到您在 Constants.ADD_CARD 操作案例上使用了 action.data,但在您的代码中您没有调度任何具有该类型的操作。你在别的地方做吗?也许这就是错误所在?

编辑:

您使用.data 的另一个地方是在您的渲染器中:this.props.cards.datastate.main 的值是多少? 你是如何创建你的 rootReducer 的?应该是这样的:

const rootReducer = combineReducers({
  main: FlashCard,
  loading: Loading,
});

你在用main吗?或者cards

【讨论】:

  • 我现在没用,修复了这个bug后再用。
  • 您的问题可能出在 rootReducer 创建上。请检查编辑?
  • 我从 react-router-redux 导入 routerReducer
  • 我认为我应该在完全获取数据后错误加载
  • so... 你在哪里声明 main 正在使用 FlashCard 减速器的结果?
【解决方案2】:

最后,我解决了我的问题:

在我的 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)
            });
    }
};

并在减速器中将 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;
    }
};

【讨论】:

    猜你喜欢
    • 2017-04-11
    • 1970-01-01
    • 1970-01-01
    • 2016-06-14
    • 2016-01-08
    • 2020-04-16
    • 1970-01-01
    • 2013-10-30
    • 1970-01-01
    相关资源
    最近更新 更多