前言 使用react-redux的朋友都經歷過這種痛苦吧? 定義一個store倉庫,首先創建各種文件,比如reducer、action、store...,然後 將redux和react連接使用。整個流程繁瑣,寫起來代碼冗餘。 react-redux創建倉庫,文件目錄如下: 好懷念使用 vuex創建寫 ...
前言
使用react-redux的朋友都經歷過這種痛苦吧?
定義一個store倉庫,首先創建各種文件,比如reducer、action、store...,然後 將redux和react連接使用。整個流程繁瑣,寫起來代碼冗餘。
react-redux創建倉庫,文件目錄如下:
好懷念使用 vuex創建寫倉庫的日子.......
直到有一天我發現了redux-toolkit ,原來redux還能這樣寫呀!
什麼是redux-toolkit
redux-toolkit 是官方推薦的編寫redux邏輯的方法,簡化了redux的配置過程,無需再創建actions、reducer的,更大程度方便使用redux倉庫
基本使用
redux-toolkit的使用步驟,可分為如下5步
- 1、安裝 redex-toolkit
- 2、創建slices
- 3、創建store
- 4、將Redux連接到React應用(provide)
- 5、在React組件中使用(useSelector、useDispath)
環境配置
vscode
React Redux Toolkit RTK Quer
安裝npm
npm i redux react-redux @reactjs/toolkit
創建切片 slices
一個切片是一個包含 reducer 函數和 action creator 的對象。它定義了一部分狀態和與該狀態相關的操作。
// sliceTbale.js
import { createSlice } from '@reduxjs/toolkit';
const moviesSlice = createSlice({
name: 'movies',
// c初始化狀態
initialState: {
currentData:[],//
tableData:[]
},
reducers: {
delete_table: (state, { payload }) => {
// 通過篩選實現刪除
state.currentTable = state.currentTable.filter((item:{id:any})=>{
return item.id !== payload.id
})
state.table = state.currentTable
message.success('刪除成功')
},
},
});
export const { addMovie } = moviesSlice.actions; // 導出 action creator
export default moviesSlice.reducer; // 導出 reducer
創建倉庫-store
我們使用 configureStore 函數來創建 Redux Store,並使用剛剛創建的 reducer 將切片與 Store 關聯起來。
// 創建store倉庫
import { configureStore } from "@reduxjs/toolkit";
import initTable from "./module/table";
const reduxStore = configureStore({
reducer: {
// xxx: xxx,
table:initTable
},
})
export default reduxStore
redux鏈接react
完成以上步驟,redux配置ok啦,如何讓整個項目中應用redux呢?
使用Provider
包裹 React頂層組件,將 Redux store 對象傳遞給組件樹中的所有組件,使得 Redux 的狀態管理能夠在整個應用程式中生效。
打開項目的入口文件 index.tsx,代碼如下:
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import RouterConfig from './router/routerConfig';
import RouterView from './router/routerView';
import "nprogress/nprogress.css" // 樣式
import { Provider } from 'react-redux';
import reduxStore from './store';
const root = ReactDOM.createRoot(
document.getElementById('root') as HTMLElement
);
root.render(
<React.StrictMode>
<Provider store={reduxStore}>
<RouterView config={RouterConfig}></RouterView>
</Provider>
</React.StrictMode>
);
組件中使用redux
使用狀態和操作:在組件中,可以使用 useSelector 和 useDispatch 鉤子來訪問狀態和觸發 action。
import React, { useEffect, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
interface IndexProps {}
const Index: React.FC<IndexProps> = (props) => {
// 獲取redux倉庫數據
const tableState = useSelector((state:any)=>state.table)
// 創建redux 派發器
const Dispath = useDispatch()
console.log('table倉庫數據',tableState)
return (
<>
{tableState.currentData.length}
</>
);
};
export default Index;
進階使用
redux中如何執行非同步呢?
createAsyncThunk
創建非同步操作, 通常用於發出非同步請求。
createAsyncThunk
創建一個非同步action,方法觸發的時候會有三種狀態:
- pending(進行中)
- fulfilled(成功)
- rejected(失敗)
export const getMovieData:any = createAsyncThunk('sliceTable/getMovie',
async () => {
const res= await getMovieListApi();
return res;
}
);
完整示例
import { createSlice, createAsyncThunk } from "@reduxjs/toolkit";
import { getMovieListApi } from "../../API/home";
import { message } from "antd";
// // createAsyncThunk 創建非同步操作, 通常用於發出非同步請求。
// createAsyncThunk 創建一個非同步action,方法觸發的時候會有三種狀態:
// pending(進行中)、fulfilled(成功)、rejected(失敗)
export const getMovieData: any = createAsyncThunk('sliceTable/getMovie',
async () => {
const res = await getMovieListApi();
return res;
}
);
const sliceName = createSlice({
name: "sliceTable",
initialState: {
table: [],
currentTable: []
},
reducers: {
initTable: (state, { payload }) => {
// console.log('初始化sliceTable數據')
},
delete_table: (state, { payload }) => {
// 通過篩選實現刪除
state.currentTable = state.currentTable.filter((item:{id:any})=>{
return item.id !== payload.id
})
state.table = state.currentTable
message.success('刪除成功')
},
serach_table: (state, { payload }) => {
// 通過篩選實現刪除
console.log('payload',payload)
state.currentTable = state.table.filter((item:{name:string})=>{
return item.name.includes(payload)
})
},
},
// 讓 slice 處理在別處定義的 actions, // 包括由 createAsyncThunk 或其他slice生成的actions
extraReducers: builder => builder
.addCase(getMovieData.pending, (state, { payload }) => {
// state.loading = true
console.log('非同步請求 中')
})
.addCase(getMovieData.fulfilled, (state, { payload }) => {
// state.loading = false
console.log('拿到非同步數據')
state.table = payload.data.data.list
state.currentTable = payload.data.data.list
})
.addCase(getMovieData.rejected, (state, { payload }) => {
// state.loading = false
// state.error = payload
console.log('非同步操作錯誤')
})
})
export const { initTable,delete_table ,serach_table} = sliceName.actions
export default sliceName.reducer
extraReducers
// extraReducers 欄位讓 slice 處理在別處定義的 actions, // 包括由 createAsyncg 或其他slice生成的actions。
store 映射到組件props中
使用 connect 函數將 store 內的數據映射到組件 props內
讀者朋友好呀,我是王天~
嘗試做過很多事情,汽修專業肄業生,半路出道的野生程式員、前端講師、新手作者,最終還是喜歡寫代碼、樂於用文字記錄熱衷分享~
如文章有錯誤或者不嚴謹的地方,期待給於指正,萬分感謝。
如果喜歡或者 有所啟發,歡迎 star,對作者也是一種鼓勵。
微信:「wangtian3111
」,加我進王天唯一的讀者群。