NipGeihou's blog NipGeihou's blog
  • Java

    • 开发规范
    • 进阶笔记
    • 微服务
    • 快速开始
    • 设计模式
  • 其他

    • Golang
    • Python
    • Drat
  • Redis
  • MongoDB
  • 数据结构与算法
  • 计算机网络
  • 应用

    • Grafana
    • Prometheus
  • 容器与编排

    • KubeSphere
    • Kubernetes
    • Docker Compose
    • Docker
  • 组网

    • TailScale
    • WireGuard
  • 密码生成器
  • 英文单词生成器
🍳烹饪
🧑‍💻关于
  • 分类
  • 标签
  • 归档

NipGeihou

我见青山多妩媚,料青山见我应如是
  • Java

    • 开发规范
    • 进阶笔记
    • 微服务
    • 快速开始
    • 设计模式
  • 其他

    • Golang
    • Python
    • Drat
  • Redis
  • MongoDB
  • 数据结构与算法
  • 计算机网络
  • 应用

    • Grafana
    • Prometheus
  • 容器与编排

    • KubeSphere
    • Kubernetes
    • Docker Compose
    • Docker
  • 组网

    • TailScale
    • WireGuard
  • 密码生成器
  • 英文单词生成器
🍳烹饪
🧑‍💻关于
  • 分类
  • 标签
  • 归档
  • nodejs

  • css

  • 最佳实践

  • TypeScript

  • ajax

  • JavaScript

  • 前端工程化

  • React

    • React - 入门
    • React - Redux
      • Redux介绍
      • 使用
        • store目录
        • 编码
        • action传参
        • 异步操作
      • 持久化
      • 浏览器插件 - Redux DevTools
    • ReactRouter
    • 规范
  • nextjs

  • Flutter

  • 笔记

  • 前端
  • React
NipGeihou
2024-08-12
目录

React - Redux

# Redux 介绍

Redux 是 React 最常用的集中状态管理工具(全局变量),类似于 Vue 中的 Pinia(Vuex),可以独立于框架运行 作用:通过集中管理的方式管理应用的状态

为什么要使用 Redux?

  1. 独立于组件,无视组件之间的层级关系,简化通信问题
  2. 单项数据流清晰,易于定位 bug
  3. 调试工具配套良好,方便调试

# 使用

  1. Redux Toolkit (RTK)- 官方推荐编写 Redux 逻辑的方式,是一套工具的集合集,简化书写方式

  2. react-redux - 用来 链接 Redux 和 React 组件 的中间件

npm i @reduxjs/toolkit  react-redux 

# store 目录

image-20240812205614312

  1. 通常集中状态管理的部分都会单独创建一个单独的 store 目录

  2. 应用通常会有很多个子 store 模块,所以创建一个 modules 目录,在内部编写业务分类的子 store

  3. store 中的入口文件 index.js 的作用是组合 modules 中所有的子模块,并导出 store

# 编码

store/modules/counterStore.js

import { createSlice } from '@reduxjs/toolkit'

// 1. 创建模块
const counterStore = createSlice({
  // 定义模块名称,独一无二
  name: 'counter',
  // 定义初始数据
  initialState: {
    count: 1
  },
  // 定义修改数据的同步方法
  reducers: {
    increment (state) {
      state.count++
    },
    decrement(state){
      state.count--
    }
  }
})

// 2. 解构出actionCreater 修改方法
const { increment,decrement } = counterStore.actions

// 获取reducer函数
const counterReducer = counterStore.reducer

// 导出
export { increment, decrement }
export default counterReducer

store/index.js :注册子模块

import { configureStore } from '@reduxjs/toolkit'

import counterReducer from './modules/counterStore'

export default configureStore({
  reducer: {
    // 1. 注册子模块为counter
    counter: counterReducer
  }
})

index.js :Provider 包裹 App 使 redux 生效

import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'
+// 导入store
+import store from './store'
+// 导入store提供组件Provider
+import { Provider } from 'react-redux'

ReactDOM.createRoot(document.getElementById('root')).render(
  // 提供store数据
+  <Provider store={store}>
    <App />
+  </Provider>
)

App.js :读取与修改

// useDispatch(写操作) useSelector(读操作)
import {useDispatch, useSelector} from "react-redux";
import {decrement, increment} from "./store/modules/counterStore";


function App() {
    const { count } = useSelector(state => state.counter)
    const dispatch = useDispatch()
    return (
        <div>
            <button onClick={()=>dispatch(decrement())}> -</button>
            {count}
            <button onClick={()=>dispatch(increment())}> +</button>
        </div>
    );
}

export default App;

image-20240812221219557

# action 传参

image-20240812221420640

# 异步操作

channelStore.js

import { createSlice } from '@reduxjs/toolkit'
import axios from 'axios'

const channelStore = createSlice({
  name: 'channel',
  initialState: {
    channelList: []
  },
  reducers: {
    setChannelList (state, action) {
      state.channelList = action.payload
    }
  }
})


// 创建异步
const { setChannelList } = channelStore.actions
const url = 'http://geek.itheima.net/v1_0/channels'
// 封装一个函数 在函数中return一个新函数 在新函数中封装异步
// 得到数据之后通过dispatch函数 触发修改
const fetchChannelList = () => {
  return async (dispatch) => {
    const res = await axios.get(url)
    dispatch(setChannelList(res.data.data.channels))
  }
}

export { fetchChannelList }

const channelReducer = channelStore.reducer
export default channelReducer

App.js

import { useEffect } from 'react'
import { useSelector, useDispatch } from 'react-redux'
import { fetchChannelList } from './store/channelStore'

function App () {
  // 使用数据
  const { channelList } = useSelector(state => state.channel)
  useEffect(() => {
    dispatch(fetchChannelList())
  }, [dispatch])

  return (
    <div className="App">
      <ul>
        {channelList.map(task => <li key={task.id}>{task.name}</li>)}
      </ul>
    </div>
  )
}

export default App

# 持久化

Redux 不支持持久化,浏览器刷新即会清除数据,需要配合 localStorage 方法来实现

initialState: {
    // 初始化时,先从localStorage取,取不到再set空串
    token: localStorge.getItem('token_key') || ''
}

setToken(state,action){
    // set的时候依次set到redux和localStorage
    state.token = action.payload
    localStorage.setItem('token_key',action,payload)
}

笔记

可将操作 localStorage 中 token 的方法封装起来,使用 getToken 、 setToken 、 removeToken 来操作

# 浏览器插件 - Redux DevTools

https://chromewebstore.google.com/detail/redux-devtools/lmhkpmbekcpmknklioeibfkpmmfibljd?hl=en (opens new window)

Redux 官方提供了针对于 Redux 的调试工具,支持实时 state 信息展示,action 提交信息查看等

image-20240813113535159

上次更新: 2024/08/28, 13:22:10
React - 入门
ReactRouter

← React - 入门 ReactRouter→

最近更新
01
Docker Swarm
04-18
02
安全隧道 - gost
04-17
03
Solana最佳实践
04-16
更多文章>
Theme by Vdoing | Copyright © 2018-2025 NipGeihou | 友情链接
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式