一、基本使用
-
1、官网地址
-
2、在项目中直接安装
npm install @reduxjs/toolkit react-redux
-
3、查看
@reduxjs/toolkit
的依赖包其中自动集成了
thunk
处理异步的包... "dependencies": { "immer": "^9.0.1", "redux": "^4.0.0", "redux-thunk": "^2.3.0", "reselect": "^4.0.0" }, ...
-
4、在
store
文件夹下创建一个activity/slice.ts
文件import { createSlice, PayloadAction} from '@reduxjs/toolkit'; export interface ActivityState { data: any; total: number; pageNumber: number; pageSize: number; loading: boolean; // 请求数据中 error: string | null; // 是否错误 } const initialState: ActivityState = { data: [], total: 0, pageNumber: 1, pageSize: 10, loading: true, error: null, } export const activityListSlice = createSlice({ name: 'activity', initialState, reducers: { fetchStart: (state) => { // return { ...state, loading: true }; state.loading = true; }, fetchSuccess: (state, action) =>{ // return { // ...state, // loading: false, // data: action.payload.data, // total: action.payload.total, // pageNumber: action.payload.pageNumber, // pageSize: action.payload.pageNumber, // }; state.loading = false; state.data = action.payload.data; state.total = action.payload.total; state.pageNumber = action.payload.pageNumber; state.pageSize = action.payload.pageSize; }, fetchFail: (state, action: PayloadAction<string | null>) => { state.loading = false; state.error = action.payload; } } })
-
5、在
store
的入口文件中合并reducer
mport { combineReducers, configureStore } from '@reduxjs/toolkit'; import { activityListSlice } from './activity/slice'; // 合并多个reducer const rootReducer = combineReducers({ ... activity: activityListSlice.reducer, }) const store = configureStore({ reducer: rootReducer, // 可以添加自己的中间件,比如打印日志的 middleware: (getDefaultMiddleware) => [...getDefaultMiddleware()], devTools: true, }); // 获取全部store数据类型 export type RootState = ReturnType<typeof store.getState>; export default store;
-
6、在页面组件中直接调用远程
api
接口import React, { PropsWithChildren, useEffect } from 'react'; import { RouteComponentProps } from 'react-router-dom'; import {useDispatch} from 'react-redux'; import { useSelector } from '../../redux/hooks'; import { activityListSlice } from '../../redux/activity/slice'; import axios from 'axios'; interface MatchParams { id: string; } type Props = PropsWithChildren<RouteComponentProps<MatchParams>>; export const Detail: React.FC<Props> = (props: Props) => { console.log(props); const loading = useSelector(state =>state.activity.loading); const activityList = useSelector(state => state.activity.data); const dispatch = useDispatch(); // 页面一进来就加载数据 useEffect(() => { const fetchData = async () => { dispatch(activityListSlice.actions.fetchStart()); try { const { data } = await axios.get('https://xxxx/api/v1/front/activity'); const {code, message, result} = data; if (Object.is(code, 0)) { dispatch(activityListSlice.actions.fetchSuccess(result)); } else { dispatch(activityListSlice.actions.fetchFail(message)); } } catch(e) { dispatch(activityListSlice.actions.fetchFail(e.messages)); } } fetchData(); }, []); if (loading) { return <h1>数据加载中</h1> } return ( <div> { activityList.map(item => { return <li key={item.id}>{item.title}</li> }) } </div> ) }
二、将请求后端接口也放到redux
中去
-
1、定义请求方法
import { createSlice, PayloadAction, createAsyncThunk} from '@reduxjs/toolkit'; import axios from 'axios'; export const getActivityList = createAsyncThunk( 'activity/getActivityList', // 唯一的 async (params:any, thunkAPI) => { console.log(params, '接口需要的参数'); thunkAPI.dispatch(activityListSlice.actions.fetchStart()); try { const { data } = await axios.get('https://test.dancebox.cn/api/v1/front/activity'); const { code, message, result } = data; if (Object.is(code, 0)) { thunkAPI.dispatch(activityListSlice.actions.fetchSuccess(result)); } else { thunkAPI.dispatch(activityListSlice.actions.fetchFail(message)); } } catch (e) { thunkAPI.dispatch(activityListSlice.actions.fetchFail(e.messages)); } } );
-
2、在页面中调用方法
useEffect(() => { dispatch(getActivityList({name: '哈哈', age:20})); }, []);
三、另外一种官方推荐的请求接口的方式
-
1、在
redux
中定义export const getActivityList = createAsyncThunk( 'activity/getActivityList', async (params:any) => { console.log(params, '接口需要的参数'); const { data } = await axios.get('https://test.dancebox.cn/api/v1/front/activity'); return data; } ); export const activityListSlice = createSlice({ name: 'activity', initialState, reducers: { }, // 注意这个位置是在extraReducers中 extraReducers: { [getActivityList.pending.type]: (state) => { state.loading = true; }, [getActivityList.fulfilled.type]: (state, action) => { const { code, message, result: {data, total, pageSize, pageNumber} } = action.payload; if (Object.is(code, 0)) { state.loading = false; state.data = data; state.total = total; state.pageNumber = pageNumber; state.pageSize = pageSize; } else { state.loading = false; state.error = message; } }, [getActivityList.rejected.type]: (state, action: PayloadAction<string | null>) => { state.loading = false; state.error = action.payload; } } })
-
2、在页面中调用
useEffect(() => { dispatch(getActivityList({name: '哈哈', age:20})); }, []);