React Native 数据请求时如何合并加载状态调度与请求逻辑?
简化加载状态与请求逻辑的三种实现方案
方案1:封装通用dispatch工具(侵入性最低,无需修改现有逻辑)
把重复的loading状态调度逻辑封装为公共工具函数,所有请求场景直接调用即可:
工具函数实现
// 通用带全局loading的dispatch封装 export const dispatchWithLoading = async (dispatch, asyncAction) => { dispatch(SetLoadingState(true)) try { // unwrap()用于把thunk的响应转为正常promise错误抛出 return await dispatch(asyncAction).unwrap() } finally { dispatch(SetLoadingState(false)) } }
业务代码调用
dispatchWithLoading(dispatch, AddAddress({...args})) .then((payload) => { if (payload.status === 'Success') navigation.goBack() })
方案2:监听createAsyncThunk状态(适合用Redux Toolkit异步方案的场景)
如果你的AddAddress是通过createAsyncThunk创建的异步action,可以直接在slice中自动匹配请求状态更新loading,无需在业务层手动处理:
调整slice配置
const appSlice = createSlice({ name: 'app', initialState, reducers: { SetLoadingState(state, action) { state.isLoading = action.payload } }, // 新增异步action状态监听 extraReducers: (builder) => { builder .addCase(AddAddress.pending, (state) => state.isLoading = true) .addCase(AddAddress.fulfilled, (state) => state.isLoading = false) .addCase(AddAddress.rejected, (state) => state.isLoading = false) } })
业务代码调用
// 无需手动处理loading状态 dispatch(AddAddress({...args})) .then(({ payload }) => { if (payload.status === 'Success') navigation.goBack() })
方案3:全局中间件自动处理(适合大量请求需要统一加载状态的场景)
如果项目中有大量异步请求都需要触发全局loading,可以写一个Redux中间件自动匹配所有thunk的请求状态,完全不需要在业务层或者slice中写额外逻辑:
中间件实现
const globalLoadingMiddleware = (store) => (next) => (action) => { // 匹配RTK createAsyncThunk生成的标准action类型后缀 if (action.type.endsWith('/pending')) { store.dispatch(SetLoadingState(true)) } else if (action.type.endsWith('/fulfilled') || action.type.endsWith('/rejected')) { store.dispatch(SetLoadingState(false)) } return next(action) }
注册到store
// 配置store时加入中间件 export const store = configureStore({ reducer: rootReducer, middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(globalLoadingMiddleware) })
优化提示
如果存在并行请求场景,建议把布尔类型的isLoading改为计数类型loadingCount:
- pending状态时
loadingCount += 1 - fulfilled/rejected状态时
loadingCount -= 1 - 最终显示loading的条件为
loadingCount > 0
避免多个请求并行时,第一个请求结束就提前关闭加载状态的问题。
内容的提问来源于stack exchange,提问作者Mazs Li
相关产品推荐
相关产品推荐

