React Redux-加载状态变慢-如何解决

时间:2020-07-16 12:29:43

标签: reactjs react-redux

我正在尝试为我的Redux创建加载状态,但它看起来“变慢”以获取更新。

第一个操作 fetchDB => setLoading:true =>一次超过setLoading:false

第二个操作 fetchCat =>没有时间触发崩溃

非常简单:

设置加载操作:

export const setLoading = () => {
  return async (dispatch) => {
    await dispatch({ type: SET_LOADING }); // no payload by default goes to true
  };
};

设置减载器:

import {
  FETCH_DB,
  SET_LOADING,
} from "../types"

const initalState = {
  db: [],
  loading: false,
}

export default (state = initalState, action) => {
    switch (action.type) {
      
    // this like the other cases sets loading to FALSE
    case FETCH_DB:
      return {
        ...state,
        db: action.payload,
        current: null,
        loading: false,
      }

    case FETCH_CAT_FOOD:
      
      return {
        ...state,
        food: action.payload,
        loading: false,
      }
    case FETCH_CAT_DESIGN:
      return {
        ...state,
        design: action.payload,
        loading: false,
      }

    case SET_LOADING:
      return {
        ...state,
        loading: true,
      }

    default:
      return state
  }
}

然后我使用的操作会产生问题:

    export const fetchCat =  kindof => {
    
      return async dispatch => {

      dispatch(setLoading()) // looks like that it doesn't get fired

   const response = await axios
          .get(`http://localhost:5000/api/categories/${kindof}`)
          .then(results => results.data)
    
        try {
          await dispatch({ type: `FETCH_CAT_${kindof}`, payload: response })
        } catch (error) {
          console.log("await error", error)
        }
      }
    }

,然后创建问题的文件(自定义组件)。 由于categories.map未定义而崩溃。 它找不到加载:是的,因此加载程序不会停止。

import React, { useState, useEffect, Fragment } from "react"

import { Spinner } from "react-bootstrap"

import { connect, useDispatch, useSelector } from "react-redux"

import CatItem from "./CatItem" // custom component

import { fetchCat, setLoading } from "../../../store/actions/appActions"

const MapCat = ({ kindof, loading, categories }) => {
  const dispatch = useDispatch()

  useEffect(() => {
    dispatch(fetchCat(kindof)) // gives the category I want to fetch
    // eslint-disable-next-line
  }, [categories])


  if (!loading) {
    return (
      <Spinner animation="border" role="status">
        <span className="sr-only">Loading...</span>
      </Spinner>
    )
  } else {
    return (
      <Fragment>
        <div>
          {categories.map(item => (
            <CatItem item={item} />
          ))}
        </div>
      </Fragment>
    )
  }
}

const mapStateToProps = (state, kindof) =>
  ({
    loading: state.appDb.loading,
    categories: state.appDb[kindof],
  })

export default connect(mapStateToProps, { fetchCat, setLoading })(MapCat)

我认为它应该像这样工作:

加载:false(默认情况下)=> true =>提取时间=> false

但是看起来不正常。有想法吗?

2 个答案:

答案 0 :(得分:1)

  1. 首先,setLoading需要返回带有type和有效负载的普通对象
export const setLoading = () => ({ type: SET_LOADING });
  1. fetchCat中不需要then。此外,不需要异步等待调度。
export const fetchCat = (kindof) => {
  return (dispatch) => {
    dispatch(setLoading()); //<---this should now be ok.

    const response = await axios.get(`http://localhost:5000/api/categories/${kindof}`)
    //   .then((results) => results.data); //<----- not required as you are using await

    try {
      dispatch({ type: `FETCH_CAT_${kindof}`, payload: response.data }); //<--- use response.data ...also async/await for dispatch is not rquired.
    } catch (error) {
      console.log("await error", error);
    }
  };
};
  1. mapStateToProps的第二个参数是ownProps which is an object
const mapStateToProps = (state, ownProps) =>
  ({
    loading: state.appDb.loading,
    categories: state.appDb[ownProps.kindof],
  })

答案 1 :(得分:0)

您有很多不同的调用调度方式。让我把它们列出来

    dispatch(fetchCat(kindof)) // gives the category I want to fetch
    await dispatch({ type: `FETCH_CAT_${kindof}`, payload: response })

您可以看到,await基本上不是async操作的使用方式。但是,调度需要typepayload来起作用,这意味着您必须确保发送给调度的对象是正确的对象。当然Redux确实通过插件接受自定义格式,所以也许如果您将async用作输入,那么reducer也可能理解它?

请首先仔细检查每个调度,例如,编写一个仅调度一种类型的动作的函数。只有在使每个呼叫正常工作后,才可以将它们组装在一起成为一个捆绑呼叫。