我正在尝试为我的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
但是看起来不正常。有想法吗?
答案 0 :(得分:1)
setLoading
需要返回带有type
和有效负载的普通对象export const setLoading = () => ({ type: SET_LOADING });
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);
}
};
};
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
操作的使用方式。但是,调度需要type
和payload
来起作用,这意味着您必须确保发送给调度的对象是正确的对象。当然Redux
确实通过插件接受自定义格式,所以也许如果您将async
用作输入,那么reducer也可能理解它?
请首先仔细检查每个调度,例如,编写一个仅调度一种类型的动作的函数。只有在使每个呼叫正常工作后,才可以将它们组装在一起成为一个捆绑呼叫。