前端技术

Redux 学习笔记

概述

https://www.bilibili.com/video/BV11r4y1n7Sj?p=1

Redux 是 JavaScript 应用的状态容器,提供可预测的状态管理。

使用场景

  • 你有很多数据随时间而变化
  • 希望状态有一个唯一确定的来源
  • 所有状态放在顶层组件中管理不可维护

功能特点

  • 集中式的存储和管理应用的状态
  • 处理组件通讯问题时,无视组件之间的层级关系

为什么 React 要使用 Redux

React 是 DOM 的一个抽象层(UI 库),并不是 Web 应用的完整解决方案,因此 React 在涉及到数据的处理以及组件之间的通信时比较复杂。对于大型的复杂应用来说,这两方面十分关键,因此只用 React 写大型应用比较吃力。

安装 Redux

npm i redux

核心概念

https://www.bilibili.com/video/BV11r4y1n7Sj?p=3

action

描述了有事情发生这一事实,并没有描述应用如何更新 state。一个 js 对象,

包含两个属性:
  • 第一个 type 属性必填,值为字符串
  • 第二个属性可选,表示本次动作携带的数据,第二个属性名称可自定义
特点:
  • 只描述做什么
  • JS 对象,必须带有 type 属性,用于区分动作的类型
  • 根据功能的不同,可以携带额外的数据,配合该数据来完成相应功能
const action = {
  type: "add"
  payload: 3
}

reducer

一个函数,根据传入的旧状态和 action,返回新的状态

const initState = 0
const reducer = (previousState = initState, action) => {
  switch (action.type) {
    case 'add':
      return previousState + 1
    case 'addN':
      return previousState + action.payload
    default:
      return previousState
  }
}

store

存储状态的仓库,整合 action 和 reducer。是 Redux 的核心

特点:
  • 一个应用只有一个 store
  • 维护应用的状态,获取状态: store.getState()
  • 创建 store 时接收 reducer 作为参考: const store = createStore(reducer)
  • 发起状态更新时,需要分发 action: store.dispatch(action)
其他 API
  • 订阅(监听)状态变化: const unSubscribe = store.subscribe(() => {})
  • 取消订阅状态变化: unSubscribe()
import { createStore } from 'redux'
const store = createStore(reducer)

// 数据改变后的回调函数
store.subscribe(() => {
  ...
})

// 修改状态
store.dispatch(action)

执行过程

获取默认值

  • 只要创建 store,Redux 就会调用一次 reducer,且 type 是一个随机值,这次调用 reducer 的目的是获取状态的默认值,这个初始值将成为下一次调用 store.getState() 方法来获取 Redux 状态值的初始值
  • type 是随机值确保了它不会被用户业务逻辑处理,而只能去匹配默认值

更新状态

  • 当需要更新状态时,就先分发动作 store.dispatch(action)
  • Redux 内部,store 就会调用 reducer,传入:上一次的状态和action,计算出新的状态并返回
  • reducer 执行完毕后,将最新的状态交给 store,store 用最新的状态替换旧状态,状态更新完毕

React-redux

基本使用

  • 安装react、redux与react-redux
  • 按 redux 要求,创建好 store, reducer, action
  • 从 react-redux 中引入 provider, useSelector, useDispatch 来操作 redux
npm i react-redux

Provider

直接包装在根组件上,这样就不需要在每个组件都引入 store 了

<Provider store={store}>

useSelector

获取公共状态,不再需要使用 store.getState() 获取状态,state变化了就会自动更新

const 状态 = useSelector(store的数据 => 需要的部分)

useDispatch

派发action,修改数据

const dispatch = useDispatch(), dispatch(action)

根组件的文件示范

https://www.bilibili.com/video/BV11r4y1n7Sj?p=9

// 主页面
import React from 'react'
import ReactDom from 'react-dom'
import App from './App'
import store from './store'
import { Provider } from 'react-redux'
ReactDom.render {
  <Provider store={store}
    <App />
  </Provider>
  document.getElementById('root')
}

// store
...

// 子页面
import React from 'react'
import { useDispatch, useSelector } from 'react-redux'
export default function Son() {
  const dispatch = useDispatch()
  const num = useSelector((state) => state)
  return (
    <div>
      { num }
      <button onClick={() => {dispatch(type: 'add')}}></button>
    </div>
  )
}

Reducer的拆分与合并

https://www.bilibili.com/video/BV11r4y1n7Sj?p=12&vd_source=74

使用 combineReducers 函数对多个 Reducer 进行合并

import book from './book'
import user from './user'
import { combineReducers } from 'redux'

const rootReducer = combineReducers({
  book,
  user
})
内容目录

PUJI Design 朴及设计 (c) 2024. 沪ICP备17052229号