Redux-Toolkit是為了簡化使用Redux繁瑣的步驟,可以j降低使用useReducer與useContext管理狀態(tài)的頻率,而且起到項目中狀態(tài)管理規(guī)范和約束化的效果。
閱讀本文需要的前置知識:React、Redux、Typescript、Redux hooks。
Redux-Toolkit使用步驟
目前使用Redux-Toolkit管理消費redux狀態(tài)的方式。舉個例子,假設(shè)我們現(xiàn)在的業(yè)務(wù)和銀行轉(zhuǎn)賬有關(guān),有兩個狀態(tài)存在redux,分別為銀行賬號和金額:accountOfBank和amountOfBank,使用createSlice來創(chuàng)建reducer和actions:
首先安裝redux-toolkit依賴包,
npm i @reduxjs/toolkit
npm i react-redux
文件目錄
slice.ts
創(chuàng)建切片,聲明存儲狀態(tài)對象以及action。createSlice創(chuàng)建一個切片(slice),主要參數(shù):
- name:slice的標識,在redux-devtool中會顯示對應的名字;
- initialState:初始值,對象;
- reducers:對象類型以及函數(shù)類型(函數(shù)參數(shù):state和傳遞的action參數(shù));
- extraReducers:用于處理異步,比如網(wǎng)絡(luò)請求等;
creactSlice返回值是一個對象,包含所有的actions。?
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
type InitialState = {
accountOfBank: string,
amountOfBank: string
}
const initialState: InitialState = {
accountOfBank: 'JanPan Bank',
amountOfBank: '1000'
}
const slice = createSlice({
name: 'bank',
initialState,
reducers: {
updateBankAccount: (state: InitialState, action: PayloadAction<string>) => {
state.accountOfBank = action.payload;
},
updateBankAmount: (state: InitialState, action: PayloadAction<string>) => {
state.amountOfBank = action.payload;
}
}
})
export const {updateBankAccount, updateBankAmount} = slice.actions;
export default slice.reducer;
?store.ts
存在在store中,configureStore是Redux-Tookit的一個工廠函數(shù),用于創(chuàng)建Redux-Store。
store是通過傳入一個reducer(縮減器)來創(chuàng)建的,并通過getState的方法,用于返回當前的狀態(tài)值,在Typescript強類型聲明中有很大的幫助。
configureStore主要參數(shù),
- reducer:將slice的reducer傳入;
- middleware:中間件;
- devTools:是否配置devTools工具,默認為true;
import { configureStore } from "@reduxjs/toolkit";
import slice from './slice';
export const store = configureStore({
reducer: {
bank: slice
}
})
export type BankState = ReturnType<typeof store.getState>;
index.tsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import { Provider } from "react-redux";
import { store } from "./toolkit/store";
const root = ReactDOM.createRoot(
document.getElementById('root') as HTMLElement
);
root.render(
<Provider store={store}>
<App />
</Provider>
);
BankView.tsx
頁面UI組件渲染,useSelector獲取當前管理的state,state的類型可通過store.ts的getState獲取,
并且將配置在store的reducer提取解構(gòu)。
import { useDispatch, useSelector } from "react-redux";
import { BankState } from "../../toolkit/store";
import { updateBankAccount, updateBankAmount } from "../../toolkit/slice";
export const BankView = () => {
const {accountOfBank, amountOfBank} = useSelector((state: BankState) => state.bank)
const dispatch = useDispatch();
return (
<div>
<h3>accountOfBank - {accountOfBank}</h3>
<h3>amountBank - {amountOfBank}</h3>
<button onClick={() => dispatch(updateBankAccount('England'))}>
change bank account
</button>
<span> </span>
<button onClick={() => dispatch(updateBankAmount('2000'))}>
change bank amount
</button>
</div>
)
}
詳細目錄截圖如下,
經(jīng)過上面簡單的封裝就實現(xiàn)了全局狀態(tài)管理,使用簡單高效,而且可以實現(xiàn)業(yè)務(wù)與UI的解耦。
在網(wǎng)絡(luò)請求等情況通常需要異常更新、提交數(shù)據(jù)等,可通過createAynceThunk實現(xiàn),
import { createAsyncThunk, createSlice, PayloadAction } from '@reduxjs/toolkit';
type InitialState = {
accountOfBank: string,
amountOfBank: string,
creatTime: string
}
const initialState: InitialState = {
accountOfBank: 'JanPan Bank',
amountOfBank: '1000',
creatTime: '2024-04-02'
}
export const fetchAccountBank = createAsyncThunk(
'https://wwww.baidu.com',
() => {
return new Promise<string>(resolve => {
let timeId = setTimeout(() => {
clearTimeout(timeId);
resolve('2024-04-03');
}, 1000)
})
})
const slice = createSlice({
name: 'bank',
initialState,
reducers: {
updateBankAccount: (state: InitialState, action: PayloadAction<string>) => {
state.accountOfBank = action.payload;
},
updateBankAmount: (state: InitialState, action: PayloadAction<string>) => {
state.amountOfBank = action.payload;
}
},
extraReducers: (builder) => {
builder.addCase(fetchAccountBank.pending, (state: InitialState) => {
console.log('fetchAccountBank pending')
state.creatTime = 'loading...'
});
builder.addCase(fetchAccountBank.fulfilled, (state, action) => {
console.log(action.payload)
state.creatTime = action.payload;
console.log('fetchAccountBank fulfilled')
});
builder.addCase(fetchAccountBank.rejected, (state) => {
console.log('fetchAccountBank rejected')
state.creatTime = 'failed...'
})
}
})
export const {updateBankAccount, updateBankAmount,} = slice.actions;
export default slice.reducer;
因為Typescript語言有較強的類型校驗,在異步時dispatch報錯,如下
只需在使用useDispatch時,聲明泛型類型即可。
// 異步需聲明useDispatch類型
const asyncDispatch = useDispatch<AppDispatch>();
最佳實踐全部代碼如下:文章來源:http://www.zghlxwxcb.cn/news/detail-844631.html
ReduxToolkit+TypeScript最佳實踐資源-CSDN文庫文章來源地址http://www.zghlxwxcb.cn/news/detail-844631.html
到了這里,關(guān)于Redux Toolkit+TypeScript最佳實踐的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!