react+redux异步操作数据
redux中操作异步方法,主要是: 1、借助createAsyncThunk()封装异步方法;2、通过extraReducers处理异步方法触发后的具体逻辑,操作派生的state
1、异步操作的slice
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'
// 使用该类型定义初始 state
const initialState = {
  systemName: '三分之一'
}
// promise封装的定时器
function delay(ms: number, data: string) {
  return new Promise((resolve) => setTimeout(() => resolve(data), ms))
}
// AsyncThunk<void, void, AsyncThunkConfig>
// createAsyncThunk<string, string, object> :
// 第一个string: 'system/updateSystemName'
// 第二个string: updateSystemName调用时,传的参数
// object: AsyncThunkConfig 配置对象
// 详细可见 : https://redux-toolkit.js.org/usage/usage-with-typescript#createasyncthunk
export const updateSystemName = createAsyncThunk<string, string>(
  'system/updateSystemName',
  async (data, config): Promise<string> => {
    console.log(data, config)
    const res = await delay(2000, data)
    return res as string
  }
)
const systemSlice = createSlice({
  name: 'system',
  initialState,
  reducers: {},
  extraReducers: (builder) => {
    // 触发updateSystemName,执行builder.addCase的回调
    builder.addCase(updateSystemName.fulfilled, (state, action) => {
      // action: {
      //   type: 'system/updateSystemName/fulfilled'
      // },
      // payload: dispatch(updateSystemName('单点的')) updateSystemName
      // meat: {arg: '单点的', ...}
      state.systemName = action.payload
    })
  }
})
export default systemSlice.reducer
AsyncThunkConfig 如图所示:
 
2、组件中调用异步的方法
import { updateSystemName } from '@/store/reducers/systemSlice'
import { RootState } from '@/store'
import { useAppDispatch } from '@/hooks/useAppDispatch'
import { useAppSelector } from '@/hooks/useAppSelector'
const Home = () => {
  const { systemName } = useAppSelector(
    (state: RootState) => state.systemReducer
  )
  const dispatch = useAppDispatch()
  const test = () => {
    // useDispatch() 返回值函数默认期望的参数类型是 AnyAction
    // 异步处理是updateSystemName: AsyncThunkAction
    // 所以这块使用官网推荐的自定义封装的hooks: useAppDispatch
    dispatch(updateSystemName('单点的'))
  }
  return (
    <>
      <div>home page</div>
      <p>{systemName}</p>
      <button onClick={test}>测试</button>
    </>
  )
}
export default Home
4、给dispatch()参数添加Action类型
解决: 类型“AsyncThunkAction<string, string, AsyncThunkConfig>”的参数不能赋给类型“AnyAction”的参数。
- useAppDispatch
import type { AppDispatch } from '@/store'
import { useDispatch } from 'react-redux'
// 给useDispatch 添加泛型, 默认接收的参数是AnyAction
// import {  useDispatch } from 'react-redux'
export const useAppDispatch = () => useDispatch<AppDispatch>()
- useAppSelector
import type { RootState } from '@/store'
import { TypedUseSelectorHook, useSelector } from 'react-redux'
// import { useSelector } from 'react-redux'
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector
- store中
 export type RootState = ReturnType<typeof store.getState>
 export type AppDispatch = typeof store.dispatch
import { configureStore } from '@reduxjs/toolkit'
import { combineReducers } from 'redux'
// 数据持久化
import { persistStore, persistReducer } from 'redux-persist'
import storageLocation from 'redux-persist/lib/storage' // defaults to localStorage for web    // redux-persist/lib/storage/session
// reducers
import userReducer from './reducers/userSlice'
import systemReducer from './reducers/systemSlice'
const persistConfig = {
  key: 'root',
  storage: storageLocation
}
// 持久化reducers
const persistedReducer = persistReducer(
  persistConfig,
  combineReducers({
    //数据切片
    userReducer,
    systemReducer
  })
)
const store = configureStore({
  // userReducer 模块名
  reducer: persistedReducer,
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware({
      serializableCheck: false
    })
})
// 可以订阅 store
// store.subscribe(() => console.log(store.getState(), 'userSlice'))
// 持久化的store
const persistor = persistStore(store)
export { store, persistor }
// Infer the `RootState` and `AppDispatch` types from the store itself
export type RootState = ReturnType<typeof store.getState>
// Inferred type: {posts: PostsState, comments: CommentsState, users: UsersState}
export type AppDispatch = typeof store.dispatch




![LeetCode[1508]子数组和排序后的区间和](https://img-blog.csdnimg.cn/b433e5915b6c465b8b46a1c219f84a0e.png)














