React使用@reduxjs/toolkit
前言
在开发的时候,有一些数据往往是需要贯穿整个项目的,并且是需要实时能够更新状态的,在Vue中我们会使用vuex来做全局状态管理,那么在React项目中,我们要怎么来做全局状态管理呢
在React项目中实现状态互通的方法有很多
例如:
- 使用
useContext- 使用
Redux- 使用
Mobx
本文章就教大家简单使用redux来进行状态管理,相信很多项目也是使用redux就行状态管理
安装Redux
在使用redux时,我们需要先安装所需的依赖
yarn add @reduxjs/toolkit
yarn add react-redux
配置Redux
1、新建文件
安装完成后,我们需要进行配置,先再src文件夹下创建store文件夹,并且创建index.ts
创建完成后,可以先暂时留空,我们先创建每一个模块
2、创建模块
在项目中,我们往往会全局管理多个状态,一旦状态过多,全部写在一起就容易让代码的可读性变差,所以可以根据业务类型进行拆分,这边先拆分一个user模块,在store文件夹下新建module文件下,用于存放全部的模块
在module文件夹下创建user.ts来管理user模块的全局状态
import { createSlice } from '@reduxjs/toolkit'
import type { PayloadAction } from '@reduxjs/toolkit'
// 菜单的接口
interface Imenu {
id: number
path: string
meniName: string
icon: string
children?: Imenu[]
}
// 用户信息接口
interface IUserInfo {
id: number
userNmae: string
avatar: string
role: number
}
// userSotre接口
interface IInit {
token: string
menuList: Imenu[]
userInfo: IUserInfo | {}
}
const initialState: IInit = {
// token
token: '',
// 侧边栏菜单
menuList: [],
// 用户信息
userInfo: {},
}
export const UserSilce = createSlice({
name: 'user',
initialState,
reducers: {
// 设置token
setToken(state, { payload }) {
state.token = payload
},
// 设置侧边菜单
setMenuList(state, { payload }) {
state.menuList = payload
},
// 设置用户信息
setUserInfo(state, { payload }) {
state.userInfo = payload
},
},
})
//导出
export const { setToken, setMenuList, setUserInfo } = UserSilce.actions
export default UserSilce.reducer
3、完善文件
创建完模块后,我们回到index.ts中将所有的模块进行汇总,并创建最终的store实例
import { configureStore, combineReducers } from '@reduxjs/toolkit'
//导入模块
import UserSilce from './module/user'
//创建store实例
export const store = configureStore({
reducer: combineReducers({
//引入userSlice
user: UserSilce,
}),
})
//导出
export type RootState = ReturnType<typeof store.getState>
export type AppDispatch = typeof store.dispatch
4、新建hook
这一步可做可不做,如果使用了hook后,我们在后续使用的时候就可以不需要指定state的类型,如果没有使用hook,那么后续再每次使用state的时候都需要指定相应的类型
//使用了Hook
import { useAppDispatch, useAppSelector } from "./store/hook"
const token = useAppSelector(state => state.user.token)
const dispatch = useAppDispatch();
//未使用Hook
import { useDispatch, useSelector } from 'react-redux';
import { AppState } from "./store/index";
const token = useSelector((state: AppState) => state.user.account);
const dispatch = useDispatch()
在store文件夹下新建hook.ts,并写入下面的代码
import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux'
import type { RootState, AppDispatch } from './index'
// Use throughout your app instead of plain `useDispatch` and `useSelector`
export const useAppDispatch: () => AppDispatch = useDispatch
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector
使用Reudx
1、全局注入Redux
在src文件夹下的index.ts中注入Redux
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import { Provider } from 'react-redux';
import { store } from "./store/index"
const root = ReactDOM.createRoot(
document.getElementById('root') as HTMLElement
);
root.render(
<Provider store={store}>
<App />
</Provider>
);
2、简单例子
在app.tsx中创建一个简单的例子,点击改变token按钮后,token的值会变成this is redux
import './App.css';
import { useAppDispatch, useAppSelector } from "./store/hook"
import { setToken } from "./store/module/user"
import { Button, Space } from 'antd';
function App() {
const dispatch = useAppDispatch();
const token = useAppSelector(state => state.user.token)
const changeToken = () => {
dispatch(setToken("this is redux"))
}
return (
<div className="App">
<Space direction="vertical" size={40}>
<span>Token:{token}</span>
<Button type="primary" onClick={changeToken}>改变Token</Button>
</Space>
</div>
);
}
export default App;
进入页面时,token为空,所以页面中token的值不显示
我们点击改变token,因为修改了token的值,所以在页面上也会显示出来
补充
我们也可以在谷歌浏览器中安装redux插件Redux DevTools,可以查看到redux 的调用,以及当前redux中的值