Redux指南:React项目中如何优雅使用Redux、Redux Toolkit和Redux Persist持久化插件?

本文将从零集中介绍React Redux、Redux Toolkit、redux-persist的使用,全文将以最简单的方式介绍,以便快速上手。

1. 介绍

  • React Redux是React官方提供的Redux绑定库,它提供了一些方便的方法来连接React组件和Redux store。React Redux中文文档
  • Redux Toolkit是一个Redux工具包,它提供了一组方便的方法来简化Redux的开发。Redux Toolkit官方文档
  • redux-persist是一个Redux持久化库,它允许你将Redux store的状态保存到本地存储中,并在需要时将其恢复。redux-persist文档

2. 安装

首先,确保你已经安装了Node.jsnpm或yarn。然后,在项目的根目录下运行以下命令来安装React Redux、Redux Toolkit、redux-persist。

powershell 复制代码
# 如果使用npm
npm install react-redux @reduxjs/toolkit redux-persist

# 如果使用yarn
yarn add react-redux @reduxjs/toolkit redux-persist

目前这里最新的版本为:

json 复制代码
"react-redux": "^9.1.0",
"@reduxjs/toolkit": "^2.2.1",
"redux-persist": "^6.0.0",

3. 配置

3.1 创建store文件夹

目录结构如下:

css 复制代码
src
├─ store
 	├─ modules  
		└─ users.js
 	└─ index.js
├─ App.js
└─ index.js

3.2 编写子模块users.js

store/modules/users.js文件中进行

javascript 复制代码
// 1. 导入Reduxjs Toolkit中的createSlice方法
import { createSlice } from '@reduxjs/toolkit';
// 2. 创建一个名为users的slice
const usersSlice = createSlice({
	 name: 'users',
	 initialState: {
		 list: [],
		 count: 0,
	 },
	 reducers: {
		// 定义一个名为increment的action 因为是同步方法 支持直接修改state
		increment: (state) => {
			// 更新state.count为state.count + 1
			state.count++;
		},
		decrement: (state) => {
			// 更新state.count为state.count - 1
			state.count--;
		},
		// 定义一个名为incrementByAmount的action
		incrementByAmount: (state, action) => {
			// 更新state.count为state.count + action.payload
			state.count += action.payload;
		},
	   // 定义一个名为setUsers的action
	   setUsers: (state, action) => {
	     // 更新state.list为action.payload
	     state.list = action.payload;
	   },
	 },
})
// 3. 解构出来的actionCreater函数
const { increment, decrement, incrementByAmount, setUsers } = usersSlice.actions;

// 模拟异步返回数据
const _callQueryResult = () => {
  const start = new Date().getTime();
  function _generateRandomNumber () {
    return Math.floor(Math.random() * 1000); //生成0到100之间的随机数
  }
  return new Promise(resolve => {
    console.log('%c\n--------响应开始--------', 'color:green;');
    setTimeout(() => {
      const end = new Date().getTime();
      let arr = []
	   // 生成五个随机数
      for (let index = 0; index < 5; index++) {
        arr.push(_generateRandomNumber())
      }
      console.log(`%c--------响应结束--------\n耗时${end - start}ms\n${arr}`, 'color:red;');
      resolve(arr)
    }, 1000)
  })
}
// 异步请求数据
const fetchUsers = () => async (dispatch) => {
	 // 发送异步请求
	 const data = await _callQueryResult();
	 // 派发action,更新state.list
	 dispatch(setUsers(data));
};

// 4. 以按需导出的方式导出actionCreater
export {
	increment,
	decrement,
	incrementByAmount,
	fetchUsers
}
// 5. 以默认导出的方式导出reducer
export default usersSlice.reducer;

3.3 统一管理模块index.js

store/index.js文件中进行配置 这里以代码注释的形式进行说明😜

javascript 复制代码
// 1. 导入官方实现、开箱即用的 Redux 快速开发工具包
import { configureStore } from '@reduxjs/toolkit';
// 2. 导入持久化所需要的插件
import { persistStore, persistReducer } from 'redux-persist';
// 3. 导入本地存储插件,可选storage,cookie,session等
import storage from 'redux-persist/lib/storage'; 
// 4. 导入子模块reducers
import users from './modules/users.js';
// 4. 导入子模块end

// 持久化配置
const persistConfig = {
  key: 'root',
  storage,
  // whitelist: [users], // 需要持久化保存的模块,默认保存所有模块(语义:白名单)
  // blacklist: [], // 不需要持久化保存的模块,默认不排除任何模块(语义:黑名单)
};
// 5. 创建持久化后的reducer
const persistedReducer = persistReducer(persistConfig, rootReducer);

// 6. 创建store
const store = configureStore({
  reducer: persistedReducer,
  devTools: true, // 是否开启开发者工具,默认true
  // 配置中间件:如果使用redux-persist,则需要设置为false,否则控制台报错(非序列化数据)
  middleware: (getDefaultMiddleware) => getDefaultMiddleware({
	   serializableCheck: false,
  })
});
// 7. 创建持久化后的store
const persistor = persistStore(store);
// 8. 导出store和持久化后的store
export {
	store,
	persistor
}

3.4 全局配置注册React Redux

src/index.js文件中进行配置

  • React Redux 包含一个<Provider />组件,这使得 Redux store 能够在应用的其他地方使用:
    • 一般用它使用在整个应用的最外层
    • 它接受 Redux store 作为 props
    • 会把 store 注入到整个应用中
    • 使得应用中的任何组件都能够使用 store
  • redux-persist持久化插件为我们提供一个<PersistGate>组件
    • 它是一个容器组件,用于包裹需要持久化保存的组件,确保在持久化保存的状态加载完毕后,再渲染需要持久化保存的组件。
    • 它能够将我们之前创建的persistor作为props传递给<PersistGate>,这样就能在需要持久化保存的地方使用了。
javascript 复制代码
import React from 'react';
import ReactDOM from 'react-dom/client';
// 导入redux-persist提供PersistGate组件
import { PersistGate } from 'redux-persist/integration/react';
// 导入React Redux 提供的Provider 组件
import { Provider } from 'react-redux';
import { store, persistor } from './store/index.js';
import App from './App.js';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
	<React.StrictMode>:
		<Provider store={store}>
			<PersistGate loading={null} persistor={persistor}>
				<App />
			</PersistGate>
		</Provider>
	</React.StrictMode>
)

3.5 试验Redux

到这里就完成所有配置了,是不是迫不及待的想看下了效果呢,那我们开始写一下测试代码吧 我这里就在src/App.js文件中进行操作了,其它文件同理

  • React Redux为我们提供了的Hooks useSelectoruseSelector
  • 其中useSelector 从 store state 中读取一个值,并且可以订阅和更新
    • useSelector 接收一个函数作为参数,函数中返回你需要的state
    • 更多使用方法请查看useSelector-示例
  • useDispatch 返回 store 的 dispatch 方法让你可以去 dispatch actions。

具体使用看如下案例:

javascript 复制代码
import React, { useEffect } from 'react'
// 导入React Redux提供的Hooks
import { useDispatch, useSelector } from 'react-redux'
import { increment, decrement, fetchUsers, incrementByAmount } from './store/modules/users'

export default function App(){
	// 结构出 list
	const { list, count } = useSelector(state => state.users)
	const dispatch = useDispatch()
	// 使用useEffect触发异步请求执行
	useEffect(()=>{
		dispatch(fetchUsers())
	},[dispatch])
	return (
		<div>
			<h2>当前users中count的值为:{count}</h2>
			<div>
				<button onClick={() => dispatch(decrement())}>count+1</button>
				<button onClick={() => dispatch(decrement())}>count-1</button>
				<button onClick={() => dispatch(incrementByAmount(-10))}>count-10</button>
				<button onClick={() => dispatch(incrementByAmount(10))}>count+10</button>
				<button onClick={() => dispatch(fetchUsers())}>重新请求</button>
			</div>
			<h2>当前usersz中list的值为:{list}</h2>
			<ul>
				{list.map(item => <li key={item}>{item}</li>)}
			</ul>
		</div>
	)
}

到这里相信你也已经了解了,React Redux以及redux-persist的使用方式了,是不是很简单呢,接下来就可以开始你的业务代码了,如果本文对你有帮助,还请不要吝啬你的👍。

本文完~

相关推荐
神夜大侠4 分钟前
VUE 实现公告无缝循环滚动
前端·javascript·vue.js
明辉光焱6 分钟前
【Electron】Electron Forge如何支持Element plus?
前端·javascript·vue.js·electron·node.js
柯南二号39 分钟前
HarmonyOS ArkTS 下拉列表组件
前端·javascript·数据库·harmonyos·arkts
wyy729341 分钟前
v-html 富文本中图片使用element-ui image-viewer组件实现预览,并且阻止滚动条
前端·ui·html
前端郭德纲1 小时前
ES6的Iterator 和 for...of 循环
前端·ecmascript·es6
王解1 小时前
【模块化大作战】Webpack如何搞定CommonJS与ES6混战(3)
前端·webpack·es6
欲游山河十万里1 小时前
(02)ES6教程——Map、Set、Reflect、Proxy、字符串、数值、对象、数组、函数
前端·ecmascript·es6
明辉光焱1 小时前
【ES6】ES6中,如何实现桥接模式?
前端·javascript·es6·桥接模式
PyAIGCMaster1 小时前
python环境中,敏感数据的存储与读取问题解决方案
服务器·前端·python
baozhengw1 小时前
UniAPP快速入门教程(一)
前端·uni-app