Redux是一个JavaScript状态管理库(数据仓库,类似于vue的vuex、pina),用于管理应用程序中的状态(state)。它可以帮助开发者更好地组织和管理应用程序的数据流,使得状态的变化可预测且易于调试。

redux
用途
状态集中管理:Redux通过一个单一的存储(store)来管理应用程序的状态。这使得状态的变化更可控和可预测,避免了状态散落在整个应用中的问题。Redux的集中式状态管理使得状态的读取和更新更加方便和一致。组件通信:Redux可以作为组件之间进行通信的桥梁。通过将状态存储在Redux store中,组件可以轻松地共享和访问状态,而不需要通过繁琐的props传递。这样可以减少组件之间的耦合性,使得应用程序的组件更加灵活和可复用。状态持久化:Redux可以与其他插件(如redux-persist)结合使用,实现状态的持久化。这对于需要在刷新页面后仍然保留状态的应用程序非常有用,如登录状态、用户偏好设置等。异步处理:虽然Redux本身是一个同步的状态管理库,但可以通过中间件(如redux-thunk、redux-saga、redux-observable)来处理异步操作。这使得在Redux中处理异步操作变得更加方便和可控,如发送网络请求、处理异步数据流等。
以下是不建议使用redux的场景:
小型应用程序:如果您的应用程序非常简单,状态管理较为简单、组件之间的通信不复杂,使用Redux可能会显得过于繁琐和冗余。在这种情况下,可以考虑使用React的内置状态管理(如useState和useEffect)来管理组件的局部状态。简单的组件通信:如果您的应用程序中的组件之间的通信只涉及少量的父子组件或兄弟组件之间的数据传递,使用Redux可能会增加不必要的复杂性。在这种情况下,可以使用React的props来进行组件之间的传递。层级浅的组件树:如果您的应用程序的组件树结构较为简单且层级较浅,组件之间的状态传递相对简单,使用Redux可能会增加不必要的复杂性。在这种情况下,可以使用React的上下文(Context)来进行状态的传递。非共享状态:如果您的应用程序中的大部分状态是局部状态,即只在组件内部使用,并且不需要在多个组件之间共享,使用Redux可能会带来额外的开销和复杂性。
创建Store
安装 Redux
npm install redux
//yarn
yarn add redux
创建 Redux Store: 在应用程序的入口文件中,创建 Redux Store,并将Reducer传递给createStore函数。
例如,创建一个名为 store 的文件夹,并创建index.js文件:(单文件reducer)
import {createStore} from 'redux'
//定义state
const initState = {
count:0
}
// 定义reducer函数
const counterReducer = (state = initState, action) => {
switch(action.type){
case 'INCREMENT':
return {
...state,
count: state.count + 1
};
case 'DECREMENT':
return {
...state,
count: state.count - 1
};
default:
return state
}
}
//创建store
const store = createStore(counterReducer);
export default store;
这里创建了一个比较简单的store文件;下面在组件内使用(这里使用父子组件):
子组件:
import React, { useRef,useState,useEffect } from "react";
import store from './store';//引入store
const Children = () => {
const [count, setCount] = useState(store.getState().count);//使用store的state数据
//在 useEffect 中,我们调用了 store.subscribe 来订阅 Redux Store 的状态变化。在回调函数中,我们通过 store.getState().count 获取最新的计数器值,并使用 setCount 更新组件的状态。
//在组件销毁时(即 useEffect 的清理阶段),我们调用 unsubscribe 函数来取消订阅。
useEffect(() => {
const unsubscribe = store.subscribe(() => {
setCount(store.getState().count);
});
return () => {
unsubscribe();
};
}, []);
return (
<div>
<span>{count}</span>
</div>
);
};
export default Children
父组件:
import React, { useRef,useState,useEffect } from "react";
import ChildComponent from './children';
import store from './store';
const Counter = () => {
const [count, setCount] = useState(store.getState().count);///通过getState方法调用store的state数据
useEffect(() => {
const unsubscribe = store.subscribe(() => {
setCount(store.getState().count);
});
return () => {
unsubscribe();
};
}, []);
const increment = () => {
store.dispatch({ type: 'INCREMENT' });//通过dispatch方法调用store的reducer方法,改变store的state数据
};
const decrement = () => {
store.dispatch({ type: 'DECREMENT' });//通过dispatch方法调用store的reducer方法,改变store的state数据
};
return (
<div>
<ChildComponent />
<p>Count: {count}</p>
<button onClick={increment}>Increment</button>
<button onClick={decrement}>Decrement</button>
</div>
);
};
export default Counter

核心属性/方法
state
定义:用了一个普通对象描述应用中的State;
类似于vuex中的state,只不过store中的state对象是在单文件中直接定义的单独的对象;
//定义state
const initState = {
count:0
}
一般单一属性所对应的state对象都会定义在单独的对象中;这样reducer函数调用是,可以调用这个对象作为参数;
例如全局store的对象定义:
const globalState = {
language: 'zh',//国际化语言默认语言
username: '',//用户名
token: '',//用户对应token
assemblySize: "middle",//主题相关
themeConfig: {
// 默认 primary 主题颜色
primary: "#1890ff",
// 深色模式
isDark: false,
// 色弱模式(weak) || 灰色模式(gray)
weakOrGray: ""
}
}
getState
定义:实时获取当前的 state;
示例,组件内使用store:
import React, { useState } from "react";
import store from './store';
const Counter = () => {
const [count, setCount] = useState(store.getState().count);///通过getState方法调用store的state数据
return ();
};
export default Counter
reducer
定义:为一个 function, 包含 state 和 action 两个参数,其中 action 为一个包含 type 的对象, 并返回新的 state,
// 定义reducer函数
const counterReducer = (state = initState, action) => {
switch(action.type){
case 'INCREMENT':
return {
...state,
count: state.count + 1
};
case 'DECREMENT':
return {
...state,
count: state.count - action.number
};
default:
return state
}
}
注意点:
- reducer函数默认第一个参数state为该store子文件中的state对象;
- reducer函数参数action是个对象,必须包含type属性;可以通过传递其他属性,来进行传参;
- reducer函数返回对象,要有拓展运算符调用原state,否则可能会漏掉删除原有的state对象;
store.dispatch({ type: 'DECREMENT', number: 2 });
action
定义:在 Redux 中,Action 是一个用于描述状态变化的普通 JavaScript 对象。它是触发状态更新的唯一来源。
这里我们把reducer函数中的第二个参数actions提取出来;
一个典型的 Action 对象包含一个 type 属性来表示动作的类型,并可以包含其他需要的属性来描述动作的具体信息。下面是一个简单的 Action 示例:
在store对应文件中添加mutation-types.js文件:
//设置增加
export const SET_INCREMENT = 'SET_INCREMENT'
//设置剑法
export const SET_DECREMENT = 'SET_DECREMENT'
在store对应文件中添加action.js文件:
import * as types from './mutation-types'
export const increment = () => ({
type: types.SET_INCREMENT,
});
export const decrement = (count) => ({
type: types.SET_DECREMENT,
count: count,
});
在上述示例中,我们定义了两个 Action Creator 函数:increment 和 decrement。
increment 函数创建一个表示递增操作的 Action,它的 type 属性为 对应type文件中的SET_INCREMENT。
decrement 函数创建一个递减的方法,它的 type 属性为 对应type文件中的SET_DECREMENT。,还有参数为count。
修改store文件夹对应index.js文件:
import {createStore} from 'redux'
import * as types from './mutation-types'
//定义state
const initState = {
count:0
}
// 定义reducer函数
const counterReducer = (state = initState, action) => {
switch(action.type){
case types.SET_INCREMENT:
return {
...state,
count: state.count + 1
};
case types.SET_DECREMENT:
return {
...state,
count: state.count - action.count
};
default:
return state
}
}
//创建store
const store = createStore(counterReducer);
export default store;
组件内使用:
import React, { useRef,useState,useEffect } from "react";
import ChildComponent from './children';
import store from './store';
import {increment,decrement} from './store/action'
const Counter = (props) => {
const [count, setCount] = useState(store.getState().count);
useEffect(() => {
const unsubscribe = store.subscribe(() => {
setCount(store.getState().count);
});
return () => {
unsubscribe();
};
}, []);
const incrementCount = () => {
store.dispatch(increment());
};
const decrementCount = () => {
store.dispatch(decrement(5));
};
return (
<div>
<ChildComponent />
<p>Count: {count}</p>
<button onClick={incrementCount}>Increment</button>
<button onClick={decrementCount}>Decrement</button>
</div>
);
};
export default Counter
dispatch
定义:是一个用于触发 Action 的函数。通过调用 dispatch(action),你可以将一个 Action 分发给 Redux Store,从而触发状态的更新;
subscribe
定义:是 Redux 提供的一个方法,用于订阅 Redux Store 的状态变化。当状态发生变化时,store.subscribe 注册的回调函数将被调用。
- 在组件中订阅 Redux Store 的状态变化。在你希望监听状态变化的组件中,调用
store.subscribe,并传递一个回调函数作为参数。这个回调函数将在状态发生变化时被调用。
下面是一个示例:
import React, { useState, useEffect } from 'react';
import store from './store';
const Counter = () => {
const [count, setCount] = useState(store.getState().count);
useEffect(() => {
const unsubscribe = store.subscribe(() => {
setCount(store.getState().count);
});
return () => {
unsubscribe();
};
}, []);
const increment = () => {
store.dispatch({ type: 'INCREMENT' });
};
const decrement = () => {
store.dispatch({ type: 'DECREMENT' });
};
return (
<div>
<p>Count: {count}</p>
<button onClick={increment}>Increment</button>
<button onClick={decrement}>Decrement</button>
</div>
);
};
export default Counter;
在上面的示例中,我们在组件中使用了 useState 钩子来管理 count 状态。然后,在 useEffect 中,我们调用了 store.subscribe 来订阅 Redux Store 的状态变化。在回调函数中,我们通过 store.getState().count 获取最新的计数器值,并使用 setCount 更新组件的状态。
在组件销毁时(即 useEffect 的清理阶段),我们调用 unsubscribe 函数来取消订阅。
请注意,使用store.subscribe可能会导致性能问题,特别是在订阅的回调函数中执行复杂的操作。如果你需要更高级的状态管理和性能优化,可以考虑使用 Redux 的中间件(例如redux-thunk、redux-saga等)或其他状态管理库(如 MobX)来替代或扩展 Redux 的功能。
createStore
在 Redux 中,createStore 是一个用于创建 Redux Store 的函数。Redux Store 是应用程序的中央状态容器,用于管理应用程序的状态,并提供一些方法来访问和更新状态。
createStore 函数的基本语法如下:
import { createStore } from 'redux';
const store = createStore(reducer, initialState);
其中,reducer 是一个纯函数,用于管理状态的更新逻辑。initialState 是状态的初始值。
combineReducers
当我们创建的store中包含很多数据时,我们会根据属性分为多个子store文件,这样就包含多个reducer函数,这样就需要在主store文件的index.js文件中通过combineReducers方法合并reducer函数;
store示例
store文件夹目录结构:
\src\store
├─index.js
├─mutation-types.js
├─modules
| ├─user
| | ├─action.js
| | └reducer.js
| ├─home
| | ├─action.js
| | └reducer.js
| ├─global
| | ├─action.js
| | └reducer.js
| ├─author
| | ├─action.js
| | └reducer.js
modules文件夹中包含多个子store文件夹;
配置mutation-types.js文件:
//设置语言
export const SET_LANGUAGE = 'SET_LANGUAGE'
//设置作者名称
export const SET_AUTHOR_NAME = 'SET_AUTHOR_NAME'
//设置token
export const SET_TOKEN = 'SET_TOKEN'
//设置用户路由
export const SET_AUTH_ROUTER = 'SET_AUTH_ROUTER'
// 设置 assemblySize
export const SET_ASSEMBLY_SIZE = "SET_ASSEMBLY_SIZE";
// 设置 setDark
export const SET_DARK = "SET_DARK";
// 设置 setWeakOrGray
export const SET_WEAK_OR_GRAY = "SET_WEAK_OR_GRAY";
//设置导航菜单是否折叠
export const SET_MENU_FOLD = "SET_MENU_FOLD";
//设置侧边栏菜单选中项
export const SET_SIDEMENU_SELECTED = "SET_SIDEMENU_SELECTED";
//设置侧边栏菜单标题与路径数组
export const SET_SIDEMENU_ARRAY = 'SET_SIDEMENU_ARRAY';
//设置用户数据列表修改对话框的弹出与消失
export const SET_USER_MODIFY = 'SET_USER_MODIFY';
这里以home文件夹为例:
action.js
import * as types from '../../mutation-types'
//设置菜单栏是否折叠
export const setMenuFold = (menu) => ({
type: types.SET_MENU_FOLD,
menu
})
reducer.js
import * as types from '../../mutation-types'
const homeState = {
collapsed: true,
}
const home = (state = homeState, action) => {
switch(action.type){
case types.SET_MENU_FOLD:
return {
...state,
collapsed : !state.collapsed
};
default:
return state
}
}
export default home
index.js
import { createStore, combineReducers, compose, applyMiddleware } from 'redux'
import global from './modules/global/reducer'
import author from './modules/author/reducer'
import home from './modules/home/reducer'
import user from './modules/user/reducer'
//创建reducer
const reducer = combineReducers({
global,
author,
home,
user
})
//创建store
const store = createStore(reducer)
export { store }
通过讲解redux,我们会发现单独使用redux存在一下缺点:
- 使用
store.subscribe可能会导致性能问题,特别是在订阅的回调函数中执行复杂的操作。 - 无法处理异步操作
- 无法持久化存储
- reducer函数返回值必须包含原state,无法直接单独修改某个对象
但是redux可以使用中间件,来解决上述问题;
react-redux
当在React中使用Redux时,你通常会使用react-redux库来简化Redux状态管理的集成。以下是一个使用react-redux的示例:
使用
安装所需的库
使用npm或者yarn安装redux和react-redux:
npm install redux react-redux --save
//yarn
yarn add redux react-redux
store文件和redux一致,
在入口文件main.jsx中引入store文件:
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import "antd/dist/antd.css";
import "@/assets/style/global.less";
import "@/assets/style/common.less";
import "@/assets/style/ant.less";
import { Provider } from "react-redux";
import { store } from "./store";
ReactDOM.createRoot(document.getElementById("root")).render(
<Provider store={store}>
<App />
</Provider>
);
组件内使用:
import React from 'react';
import { connect } from 'react-redux';
import { increment, decrement } from './actions/counterActions';
const Counter = ({ count, increment, decrement }) => {
return (
<div>
<p>Count: {count}</p>
<button onClick={increment}>Increment</button>
<button onClick={decrement}>Decrement</button>
</div>
);
};
const mapStateToProps = (state) => {
return {
count: state.counter.count // 映射counterReducer的状态到组件的props
};
};
const mapDispatchToProps = {
increment,
decrement
};
export default connect(mapStateToProps, mapDispatchToProps)(Counter);
在这个示例中,我们使用connect函数来连接Counter组件和Redux store。mapStateToProps函数将counterReducer的状态映射到Counter组件的count属性。mapDispatchToProps对象将increment和decrementactions映射到组件的props。
通过以上步骤,你可以在React组件中使用Redux来管理状态,并在组件中访问和更新Redux的状态。
优点
简化状态管理:React-Redux 提供了一个统一的方式来管理应用程序的状态。通过 Redux 的 Store,可以将应用程序的状态集中存储,并以一种可预测和可维护的方式进行更新和访问。这种集中式的状态管理模式使得状态变化的追踪和调试更加容易。高效的组件通信:React-Redux 通过connect方法将 Redux 的状态和操作与 React 组件连接起来。这样,组件可以直接从状态中读取数据,并且可以通过发送 Action 来更新状态,而无需手动进行状态传递。这种高效的组件通信机制使得组件之间的数据交互更加简单和可控。性能优化:React-Redux 通过使用connect方法来优化组件的渲染性能。connect方法只会在组件所依赖的状态发生变化时才触发重新渲染;完整的生态系统:React-Redux 是 Redux 的官方绑定库,与 Redux 生态系统完美结合。它与其他 Redux 中间件和工具(如 Redux Thunk、Redux Saga 等)兼容,并与 React 开发工具链(如 React DevTools)紧密集成。这为开发者提供了一套完整而强大的工具和库,可以更快地构建复杂的 React 应用程序。可测试性:使用 React-Redux 构建的应用程序很容易进行单元测试和集成测试。由于状态逻辑被抽离到 Redux 中,组件变得更加纯粹和可预测。而且 Redux 提供了一些工具和模式,使得测试变得简单和可靠。
redux-thunk
当在 Redux 中使用 redux-thunk 插件时,你可以在 action 中执行异步操作,并且可以访问 dispatch 和 getState 方法。
使用
使用 npm 或者 yarn 安装 redux、react-redux 和 redux-thunk:
npm install redux react-redux redux-thunk --save
//yarn
yarn add redux react-redux redux-thunk
创建包含异步操作的action.js
import * as types from './mutation-types'
export const increment = () => {
return (dispatch) => {
setTimeout(() => {
dispatch({
type: types.SET_INCREMENT,
});
}, 1000);
};
};
export const decrement = (count) => {
return (dispatch, getState) => {
const { counter } = getState();
if (counter > 0) {
dispatch({
type: types.SET_DECREMENT,
count: count,
});
}
};
};
store入口文件index.js:
import { createStore, combineReducers, compose, applyMiddleware } from 'redux'
import reduxThunk from 'redux-thunk'
import global from './modules/global/reducer'
import author from './modules/author/reducer'
import home from './modules/home/reducer'
import user from './modules/user/reducer'
//创建reducer
const reducer = combineReducers({
global,
author,
home,
user
})
//使用redux中间件
const middleWares = applyMiddleware(reduxThunk)
//创建store
const store = createStore(reducer, composeEnhancers(middleWares))
export { store }
其他使用方式不变;
优点
异步操作支持:Redux Thunk 允许我们在 Redux 中处理异步操作,例如发送网络请求或执行定时任务。它通过允许 Action 创建函数返回一个函数而不仅仅是一个普通的对象,使得我们可以在该函数中执行异步操作。这样,我们可以更容易地管理和调度异步操作,保持 Redux 的状态一致性。
redux-promise
当在 Redux 中使用 redux-promise 中间件时,你可以在 action 中返回一个 Promise 对象,redux-promise 会自动处理这个 Promise,并根据 Promise 的状态触发相应的 action。
使用
使用 npm 或者 yarn 安装 redux、react-redux 和 redux-promise:
npm install redux react-redux redux-promise --save
//yarn
yarn add redux react-redux redux-promise
store入口文件index.js:
import { createStore, combineReducers, compose, applyMiddleware } from 'redux'
import promiseMiddleware from 'redux-promise';
import global from './modules/global/reducer'
import author from './modules/author/reducer'
import home from './modules/home/reducer'
import user from './modules/user/reducer'
//创建reducer
const reducer = combineReducers({
global,
author,
home,
user
})
//使用redux中间件
const middleWares = applyMiddleware(promiseMiddleware)
//创建store
const store = createStore(persistReducerConfig, composeEnhancers(middleWares))
export { store }
在action.js中使用异步操作:
import axios from 'axios';
import * as types from '../../mutation-types'
export const fetchData = () => {
return {
type: types.FETCH_DATA,
payload: axios.get('https://api.example.com/data')
};
};
优点
简化异步操作:redux-promise 可以帮助简化在 Redux 应用中处理异步操作的代码。它允许你在 action 中返回一个 Promise 对象,而不是手动编写异步操作的代码。redux-promise 会自动处理这个 Promise 并触发相应的 action。
redux-immer
redux-immer 是一个用于在 Redux 应用中使用不可变数据更新的库。它可以让你以一种更简洁的方式更新 Redux 的状态,而不需要手动创建深拷贝的副本。
使用
使用 npm 或者 yarn 安装 redux、react-redux 和 redux-immer:
npm install redux react-redux redux-immer --save
//yarn
yarn add redux react-redux redux-immer
修改reducer文件:
produce 是 redux-immer 库提供的一个函数,它可以帮助在 Redux reducer 中创建不可变的状态更新。 produce 函数接受一个当前状态(draft)和对状态进行修改的函数作为参数,并返回一个新的不可变的状态。
import produce from 'immer'
import * as types from '../../mutation-types'
const homeState = {
collapsed: true,
}
const home = (state = homeState, action) =>
//没有大括号
produce(state, draftState => {
switch (action.type) {
case types.SET_MENU_FOLD:
draftState.collapsed = !draftState.collapsed
break
default:
return draftState
}
})
export default home
在 reducer 中使用了 produce 函数来创建一个新的不可变状态。在 produce 的第一个参数中,我们传递了当前的状态(draft),在第二个参数中,我们传递了一个函数,该函数用于修改状态。在这个函数中,我们直接修改了 draft 对象的属性值,而不必创建副本。
produce 函数会根据对状态的修改,自动创建一个不可变的状态,并返回它。Redux 会检测到状态的变化,从而触发相关的订阅和更新。
这样,我们就可以使用 produce 函数轻松地编写 immutable(不可变的)代码,而不必手动创建副本和深层嵌套的更新。
redux-persist
redux-persist 是一个用于在 Redux 应用中持久化状态的库。它可以将 Redux 的状态保存到本地存储中,并在应用重新加载时自动还原状态
使用
使用 npm 或者 yarn 安装 redux、react-redux、redux-persist 和相应的存储引擎库,例如 redux-persist-local-storage:
npm install redux react-redux redux-persist redux-persist-local-storage --save
//yarn
yarn add redux react-redux redux-persist redux-persist-local-storage
store入口文件index.js:
import { createStore, combineReducers, compose, applyMiddleware } from 'redux'
import { persistStore, persistReducer } from 'redux-persist'
import storage from 'redux-persist/lib/storage'
import reduxThunk from 'redux-thunk'
import reduxPromise from 'redux-promise'
import global from './modules/global/reducer'
import author from './modules/author/reducer'
import home from './modules/home/reducer'
import user from './modules/user/reducer'
//创建reducer
const reducer = combineReducers({
global,
author,
home,
user
})
//redux持久化设置
const persistConfig = {
key: 'redux-state',
storage: storage
}
const persistReducerConfig = persistReducer(persistConfig, reducer)
//开启浏览器调试者工具
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
//使用redux中间件
const middleWares = applyMiddleware(reduxThunk, reduxPromise)
//创建store
const store = createStore(persistReducerConfig, composeEnhancers(middleWares))
//创建持久化仓库
const persistor = persistStore(store)
export { store, persistor }
全局入口文件main.jsx:
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'
import 'antd/dist/antd.css'
import '@/assets/style/global.less'
import '@/assets/style/common.less'
import '@/assets/style/ant.less'
import { PersistGate } from "redux-persist/integration/react";
import { Provider } from 'react-redux'
import { store, persistor } from './store'
import '@/mock'
ReactDOM.createRoot(document.getElementById('root')).render(
<Provider store={store}>
<PersistGate persistor={persistor}>
<App />
</PersistGate>
</Provider>,
)
在这个示例中,我们使用 redux-persist 的 persistReducer 函数来创建一个持久化的根 reducer。我们还需要使用 redux-persist 的 persistStore 函数来创建一个持久化的 Redux store。持久化配置包含一个 key,用于标识存储的数据,以及一个存储引擎,例如 redux-persist-local-storage,用于实际的数据存储。
优点
状态持久化:redux-persist 可以帮助在 Redux 应用中实现状态的持久化。它可以将 Redux 的状态保存到本地存储中(如 localStorage、AsyncStorage 等),并在应用重新加载时自动还原状态。这使得用户可以在应用关闭并重新打开后,继续使用之前保存的状态,提供了良好的用户体验。简化数据管理:redux-persist 简化了 Redux 应用的数据管理。它提供了一个易于使用的 API,使得将状态保存到本地存储和从本地存储还原状态变得非常简单。开发者不需要手动编写复杂的逻辑来处理数据的读写,而是可以依赖 redux-persist 来自动处理这些操作。跨平台支持:redux-persist 不仅适用于 React Native,还可以在 Web、Electron、React Native 等多个平台上使用。这使得开发者可以在不同的平台上共享相同的状态持久化逻辑,提高了代码的复用性和可维护性。
缺点
性能开销:由于 redux-persist 需要在每次状态变化时进行序列化和反序列化操作,所以可能会引入一定的性能开销。特别是当状态较大或频繁变化时,性能问题可能会变得更加明显。开发者应该在使用 redux-persist 时考虑到这一点,并根据实际情况做出权衡。存储限制:由于 redux-persist 将状态保存到本地存储中,所以会受到本地存储的限制。不同的存储引擎和浏览器可能对存储的数据量有不同的限制。开发者应该了解存储引擎的限制,并确保存储的数据量不超过限制,以避免出现问题。数据安全性:由于 redux-persist 将状态保存到本地存储中,所以数据的安全性可能会受到威胁。如果存储的数据包含敏感信息,如用户凭据等,开发者应该采取适当的安全措施来保护这些数据。
redux-toolkit
Redux Toolkit 是一个官方推荐的用于简化 Redux 开发的工具集。它提供了一些实用的函数和模式,可以帮助我们更快、更简洁地编写 Redux 相关的代码。
使用
使用 npm 或者 yarn 安装 redux、react-redux 和 @reduxjs/toolkit:
npm install redux react-redux @reduxjs/toolkit --save
创建Reducers
counterSlice.js
import { createSlice } from '@reduxjs/toolkit';
const counterSlice = createSlice({
name: 'counter',
initialState: 0,
reducers: {
increment: (state) => state + 1,
decrement: (state) => state - 1
}
});
export const { increment, decrement } = counterSlice.actions;
export default counterSlice.reducer;
todoSlice.js
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
export const fetchTodos = createAsyncThunk('todos/fetchTodos', async () => {
// 异步获取待办事项
const response = await fetch('https://api.example.com/todos');
const data = await response.json();
return data;
});
const todoSlice = createSlice({
name: 'todos',
initialState: [],
reducers: {
addTodo: (state, action) => {
state.push(action.payload);
},
deleteTodo: (state, action) => {
return state.filter((todo) => todo.id !== action.payload);
}
},
extraReducers: (builder) => {
builder.addCase(fetchTodos.fulfilled, (state, action) => {
return action.payload;
});
}
});
export const { addTodo, deleteTodo } = todoSlice.actions;
export default todoSlice.reducer;
在这个示例中,我们创建了两个Slice来分别管理计数器和待办事项的状态和操作。counterSlice定义了计数器的reducer和action,而todoSlice定义了待办事项的reducer和action,并使用createAsyncThunk来处理异步操作。
store入口index.js文件:
import { combineReducers, configureStore } from '@reduxjs/toolkit';
import counterReducer from './counterSlice';
import todoReducer from './todoSlice';
const rootReducer = combineReducers({
counter: counterReducer,
todos: todoReducer
});
const store = configureStore({
reducer: rootReducer
});
export default store;
其他文件使用方式不变;
组件内使用:
在使用 Redux Toolkit 内置的 createSlice 函数创建 Redux store 和 reducer 之后,你可以在组件中使用 useSelector 和 useDispatch 钩子来访问 Redux store 中的状态和派发 action。下面是一个示例:
import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { increment, decrement } from './counterSlice';
const Counter = () => {
const count = useSelector((state) => state.counter); // 通过 useSelector 获取 counterReducer 中的状态
const dispatch = useDispatch(); // 获取 dispatch 函数
return (
<div>
<p>Count: {count}</p>
<button onClick={() => dispatch(increment())}>Increment</button>
<button onClick={() => dispatch(decrement())}>Decrement</button>
</div>
);
};
export default Counter;
在这个示例中,我们使用 useSelector 钩子来订阅 Redux store 中的状态,通过回调函数返回所需的状态(在这个例子中是 state.counter),并将其赋值给 count 变量。使用 useDispatch 钩子获取 dispatch 函数,用于派发相应的 action。
然后,我们在组件中使用 count 变量来显示计数器的值,并通过 dispatch 函数来派发 increment 和 decrement action。
通过这种方式,你可以在组件中方便地使用 Redux Toolkit 创建的 Redux store,并与状态进行交互。