React使用@reduxjs/toolkit

668 阅读3分钟

React使用@reduxjs/toolkit

前言

在开发的时候,有一些数据往往是需要贯穿整个项目的,并且是需要实时能够更新状态的,在Vue中我们会使用vuex来做全局状态管理,那么在React项目中,我们要怎么来做全局状态管理呢

在React项目中实现状态互通的方法有很多

例如:

  1. 使用useContext
  2. 使用Redux
  3. 使用Mobx

本文章就教大家简单使用redux来进行状态管理,相信很多项目也是使用redux就行状态管理

安装Redux

在使用redux时,我们需要先安装所需的依赖

yarn add @reduxjs/toolkit
yarn add react-redux

配置Redux

1、新建文件

安装完成后,我们需要进行配置,先再src文件夹下创建store文件夹,并且创建index.ts

创建完成后,可以先暂时留空,我们先创建每一个模块

image-20220916175207674

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的值不显示

image-20220916181545960

我们点击改变token,因为修改了token的值,所以在页面上也会显示出来

image-20220916181700134

补充

我们也可以在谷歌浏览器中安装redux插件Redux DevTools,可以查看到redux 的调用,以及当前redux中的值

image-20220916181913686