=================== TLDR ===========================
@markerikson(请参阅接受的答案)友善地指出了当前的解决方案和未来的解决方案。
编辑:2020年11月15日:链接到文档以在Slice中使用异步Thunk
RTK确实通过使用thunk中间件在减速器中支持thunk(请参阅答案)。
在1.3.0版本(当前于2020年2月发布)中,提供了一个辅助方法createAsyncThunk()
createAsyncThunk,该方法将提供一些有用的功能(即,根据诺言的状态触发3个“扩展的”减速器)。
=========================原始文章2020年2月======================= ====
我对Redux并不陌生,并且遇到过Redux Toolkit(RTK),并想实现它提供的更多功能(或者在这种情况下可能不?)(2020年2月)
我的应用程序调度到通过创建的reducers切片createSlice({})
(请参见createSlice api docs)
到目前为止,它的工作非常出色。我可以轻松地使用内置的组件,dispatch(action)
并useSelector(selector)
很好地分派操作并接收/响应状态更改。
我想使用来自axios的异步调用从API提取数据并更新存储,因为请求是A)启动B)已完成。
我看过redux-thunk,似乎它完全是为此目的而设计的……但是新的RTK在createSlice()
随后的一般搜索中似乎并不支持它。
以上是使用切片实现重击的当前状态吗?
我在文档中看到您可以在slice中添加extraReducers,但是不确定是否可以创建使用thunk的传统减速器并让slice实现它们?
总的来说,这是令人误解的,因为RTK文档显示您可以使用thunk ...但是似乎没有提及它无法通过新的slice API进行访问。
const store = configureStore({
reducer: rootReducer,
middleware: [thunk, logger]
})
我的代码片段显示了异步调用将在何处失败以及其他一些有效的示例化约器。
import { getAxiosInstance } from '../../conf/index';
export const slice = createSlice({
name: 'bundles',
initialState: {
bundles: [],
selectedBundle: null,
page: {
page: 0,
totalElements: 0,
size: 20,
totalPages: 0
},
myAsyncResponse: null
},
reducers: {
//Update the state with the new bundles and the Spring Page object.
recievedBundlesFromAPI: (state, bundles) => {
console.log('Getting bundles...');
const springPage = bundles.payload.pageable;
state.bundles = bundles.payload.content;
state.page = {
page: springPage.pageNumber,
size: springPage.pageSize,
totalElements: bundles.payload.totalElements,
totalPages: bundles.payload.totalPages
};
},
//The Bundle selected by the user.
setSelectedBundle: (state, bundle) => {
console.log(`Selected ${bundle} `);
state.selectedBundle = bundle;
},
//I WANT TO USE / DO AN ASYNC FUNCTION HERE...THIS FAILS.
myAsyncInSlice: (state) => {
getAxiosInstance()
.get('/')
.then((ok) => {
state.myAsyncResponse = ok.data;
})
.catch((err) => {
state.myAsyncResponse = 'ERROR';
});
}
}
});
export const selectBundles = (state) => state.bundles.bundles;
export const selectedBundle = (state) => state.bundles.selectBundle;
export const selectPage = (state) => state.bundles.page;
export const { recievedBundlesFromAPI, setSelectedBundle, myAsyncInSlice } = slice.actions;
export default slice.reducer;
我的商店设置(商店配置)。
import { configureStore } from '@reduxjs/toolkit';
import thunk from 'redux-thunk';
import bundlesReducer from '../slices/bundles-slice';
import servicesReducer from '../slices/services-slice';
import menuReducer from '../slices/menu-slice';
import mySliceReducer from '../slices/my-slice';
const store = configureStore({
reducer: {
bundles: bundlesReducer,
services: servicesReducer,
menu: menuReducer,
redirect: mySliceReducer
}
});
export default store;
任何帮助或进一步的指导将不胜感激。
我是Redux的维护者和Redux Toolkit的创建者。
FWIW,关于使用Redux进行异步调用并不需要通过Redux Toolkit进行更改。
您仍将使用异步中间件(通常为redux-thunk
),获取数据并使用结果调度操作。
从Redux Toolkit 1.3开始,我们确实有一个名为helper的方法createAsyncThunk
,该方法可以生成动作创建者并为您请求生命周期动作调度,但是它仍然是相同的标准过程。
这些来自文档的示例代码总结了用法。
import { createAsyncThunk, createSlice } from '@reduxjs/toolkit'
import { userAPI } from './userAPI'
// First, create the thunk
const fetchUserById = createAsyncThunk(
'users/fetchByIdStatus',
async (userId, thunkAPI) => {
const response = await userAPI.fetchById(userId)
return response.data
}
)
// Then, handle actions in your reducers:
const usersSlice = createSlice({
name: 'users',
initialState: { entities: [], loading: 'idle' },
reducers: {
// standard reducer logic, with auto-generated action types per reducer
},
extraReducers: {
// Add reducers for additional action types here, and handle loading state as needed
[fetchUserById.fulfilled]: (state, action) => {
// Add user to the state array
state.entities.push(action.payload)
}
}
})
// Later, dispatch the thunk as needed in the app
dispatch(fetchUserById(123))
请参阅Redux Toolkit“使用指南:异步逻辑和数据提取”文档页面,以获取有关此主题的其他信息。
希望这能为您指明正确的方向!
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句