安装插件
npm install @reduxjs/toolkit react-redux
reduxjs/toolkit 和 react-redux 是两个关键的库,它们提供了 Redux 的工具和组件,用于管理应用的状态。下面是它们各自的功能和作用的详细解释:
- Redux 工具包 (reduxjs/toolkit):
-
- 简化 Redux 设置:它提供了一种简便的方式来创建 Redux store,使得你不需要手动编写
createStore和combineReducers等函数,同时还能集成开发者工具。 - 编写 reducer:
toolkit引入了一个名为createReducer的函数,它允许你使用一个对象来映射状态更改的逻辑,使得编写 reducer 函数更加直观和高效。 - 处理 Action:它提供了
createAction函数,该函数自动创建 action 类型和 action 创建函数,减少代码重复。 - 处理异步逻辑:
toolkit中的createAsyncThunk函数用于创建处理异步操作的 thunk action,可以方便地处理异步请求和中间状态。 - 管理切片(Slices):库中的
createSlice函数是一个高级的 reducer 创建函数,它集成了 reducer、actions 和 state 管理,大大简化了 Redux 应用的创建。
- 简化 Redux 设置:它提供了一种简便的方式来创建 Redux store,使得你不需要手动编写
- React Redux:
-
- 连接 React 和 Redux:它提供了一组组件和 API,使得 React 组件可以轻松地连接到 Redux store,订阅 store 中的状态变更。
- 组件中的状态访问:通过
connect函数(在函数组件中可以使用useSelector和useDispatchhooks),组件可以访问 Redux store 中的状态,并且可以 dispatch action。
-
- 高效的渲染:
react-redux确保组件根据 store 中的状态变化高效地渲染,并且提供了性能优化的手段,如shouldComponentUpdate或使用React.memo/React.PureComponent。
- 高效的渲染:
在实际开发中,reduxjs/toolkit 用于简化 Redux 开发过程中的繁琐操作,提高编码效率和维护性;而 react-redux 则提供了从 React 组件访问和更新 Redux store 的机制,确保组件与 Redux 状态同步更新。两者结合使用,可以构建出高效、可维护的 React 应用。
项目运用
项目中与vue使用类似, 我们会建立一个store文件夹内部用来维护所有的状态管理
store
目录结构
store
├── index.ts
└── modules
└── countStore.ts
store 文件夹:该文件夹包含了与 Redux Store 相关的文件。
index.ts:入口文件,用于导入和导出与 Redux Store 配置有关的内容。
modules 文件夹:该文件夹用于组织 Redux 模块,每个模块通常对应着应用中的一个功能领域。
store定义
// 从 reduxjs/toolkit 库中导入 createSlice 函数
import { createSlice } from '@reduxjs/toolkit';
// 使用 createSlice 创建一个名为 count 的切片
const countStore = createSlice({
// 切片的名称,用于在 Redux DevTools 中识别此切片
name: 'count',
// 初始状态,默认为 count: 0
initialState: {
count: 10
},
reducers: {
// 定义 increment reducer,用于增加 count 状态值
increment(state) {
state.count++;
},
// 定义 decrement reducer,用于减少 count 状态值
decrement(state) {
state.count--;
}
}
});
// 导出 actions,供组件分发
export const { increment, decrement } = countStore.actions;
// 导出默认的 reducer,用于更新 state
export default countStore.reducer;
定义name = count 的状态,并且可以通过分发 increment 和 decrement action 来更改这个状态。
组合store
// 导入 Redux Toolkit 提供的 configureStore 函数
import { configureStore } from '@reduxjs/toolkit';
// 导入自定义的 countReducer
import countReducer from './modules/countStore';
// 使用 configureStore 创建 Redux 存储实例
const store = configureStore({
// reducer 键值对,指定存储中的 reducer。
reducer: {
// 在存储中使用名为 countStore 的键关联 countReducer
countStore: countReducer,
},
});
// 导出 configureStore 创建的 Redux 存储实例,以便在应用程序中使用
export default store;
引用
父组件
// 从'react-redux'库导入Provider组件,它允许你将Redux store提供给所有需要它的组件
import { Provider } from 'react-redux';
// 导入Redux store实例
import store from './store';
// 导入子组件
import Child from './app';
export default () => {
// 从Redux store的状态中解构出countStore对象
const {countStore} = store.getState();
// 在组件的render方法中,返回要渲染的元素
return (
// 使用Provider组件包裹所有内容,让它们都可以访问Redux store
<Provider store={store}>
{/* 渲染一个包含根计数器计数信息的div */}
<div>this is root {countStore.count}
{/* 渲染子组件 */}
<Child />
</div>
</Provider>
)
}
通过调用Redux store对象的 getState 方法,解构出 countStore 对象。
<Provider> 组件是 react-redux 库提供的一个组件,它允许所有子组件访问Redux store
子组件
// 从'react-redux'库导入useSelector钩子,用于从Redux store中选择和访问状态
import { useSelector } from 'react-redux'
export default () => {
// 使用useSelector钩子从Redux store中解构出count值,通过指定state => state.countStore来访问countStore状态切片中的count属性
const { count } = useSelector(state => state.countStore);
return (
// 使用一个div元素作为容器
<div>
{/* 显示一条文本信息 */}
this is children
{/* 渲染解构得到的count值 */}
{count}
</div>
)
}
useSelector 是react-redux提供的一个hook, 用来访问外层Provider组件提供的store数据。useSelector 通过编写一个选择器函数来选择 Redux store 中的状态。这个选择器函数会接收整个 store 的 state 作为参数,并应该返回你想要在组件中使用的状态的一部分
修改store
还是上面的示例
// 导入 react-redux 的 useDispatch 和 useSelector 函数,分别用于分发 action 和获取 state
import { useDispatch, useSelector } from 'react-redux'
import { increment, decrement } from './store/modules/countStore'
// 定义 State 接口,用于指定 state 的类型
interface State {
countStore: {
count: number
}
}
export default () => {
const { count } = useSelector((state: State) => state.countStore)
// 使用 useDispatch 获取 Redux 的 dispatch 函数
const dispatch = useDispatch()
return (
<div>
{/* 点击按钮时,分发 decrement 函数来减少计数 */}
<button onClick={()=> { dispatch(decrement()) }}>-</button>
{/* 显示当前的计数值 */}
{count}
{/* 点击按钮时,分发 increment 函数来增加计数 */}
<button onClick={() => {dispatch(increment())}}>+</button>
</div>
)
}
要修改store,只能通过action来修改, 而执行action,需要通过dispatch来调用
所以总结来就是两步:
- 首先获取到修改的action
- 通过dispatch调用action来修改
需要传参的话, 只需要在调用action时传递过去即可。