- A+
前言
使用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
」,加我进王天唯一的读者群。