day4 Redux(React状态库)

110 阅读5分钟

Redux

react 状态管理库:flux、reduxmobx

redux 官网

redux 中文官网

redux 中文文档

JS应用的状态容器,提供可预测的状态管理。 能够实现集中式状态管理

Redux是使用action事件来管理和更新应用状态的模式和工具库。

该状态库以集中式Store(centralized store)的方式对整个应用中使用的状态进行集中管理,其规则确保状态只能以可预测的方式更新。

redux状态库和react没有任何关系,即可以在其他库或原生开发中也使用redux来实现状态管理。

概念

store

  是一个容器,由于保存整个应用中要管理状态的各项功能

state

  是整个应用中各组件间需要共享访问的数据

action

  是一个普通的对象,用于描述发生了什么,这个对象通常有`type``payload`这两个属性

action creator

  这是action创建函数,主要用于创建生成action对象,以实现对action对象的复用

reducer

这是一个纯函数,用于同步更新状态数据 reducer函数接收旧的state和action作为参数,返回新的state数据。

函数签名:(state,action) => newState

React 必需符合以下规则:

  • 仅使用stateaction参数计算新的状态值
  • 禁止直接修改state。必须通过复制现有的state并对复制的值进行更改的方式来做不可变更新(immutable updates).
  • 禁止任何异步逻辑,依据随机值或导致其他"副作用"的代码

reducer函数内部的逻辑通常遵循以下步骤:

  • 检查reducer是否关心这个action
  • 如果是,则复制state,使用新值更新state副本,然后返回新state
  • 否则,返回原来的state不变 即通常在reducer函数体内部,使用switch-case语法来实现逻辑处理

dispatch

   dispatch(action)

更新state的唯一方法是调用store.dispatch()并传入一个action对象

注意:在redux使用时,也是不能直接调用reducer()函数来更新状态数据,而是需要store.dispatch(action)来触发调用reducer()更新状态数据。

Selector

 是一个函数组件的hook,useSelector,Selector函数可以从store状态树中提取指定的片段

使用

    npm i redux //安装

定义reducer函数

  通常在`./src/reducers目录中创建reducer函数模块:`
//使用rxreducer在vscode中快速生成

import { DECREMENT, INCREMENT } from "../actions/action-types"

/**
 * 初始状态数据
 */
const initialState = {
  count: 0, // 计数数量
}

/**
 * reducer 纯函数,作用:用于同步更新状态数据
 * @param {*} state 旧的状态数据
 * @param {*} action action对象,通常有 { type, payload } 属性
 * @returns 
 */
const counterReducer = (state = initialState, { type, payload }) => {
  // 将 state 进行深复制(深克隆)
  const copyState = JSON.parse(JSON.stringify(state))

  // 根据 action.type 判断进行何种更新处理
  switch (type) {
    case INCREMENT: // 计数数量加
      copyState.count += payload.num
      return copyState // 返回新的状态数据
    case DECREMENT: // 计数数量减
      copyState.count -= payload.num
      return copyState
    default:
      return state
  }
}

export default counterReducer

定义多个独立到的reducer后,要将各独立reducer合并为一个根reducer(相当于vue中的模块)

import { combineReducers } from 'redux'
import counterReducer from './counter'
import userReducer from './user'

// 将多个独立的 reducer 合并为一个根 reducer
const rootReducer = combineReducers({
  counter: counterReducer,
  user: userReducer,
})

export default rootReducer

定义action creator函数

 通常在`./src/actions`目录下创建:
import { DECREMENT, INCREMENT } from "./action-types";

/**
* action creator函数,用于生成 action 对象
* 加数量的 action 创建函数
*/
export const incrementActionCreator = num => ({
 type: INCREMENT,
 payload: {
   num,
 },
})

创建Store

    通常在`./src/store`目录中处理:
import { createStore } from 'redux'
import rootReducer from '../reducers'

// 创建 Store 仓库
const store = createStore(rootReducer)

export default store

基于根reducer去创建Store仓库

在react中使用redux

  reduxreact没有任何关系,想在react中使用需安装一个绑定库:
  npm i react-redux // 安装绑定库

react-redux中文文档

将react与redux绑定

src的入口index.js文件中导入:
   // React 18.x 写法
import ReactDOM from 'react-dom/client'
import { Provider } from 'react-redux'
import store from './store'
import App from './App'
// 创建 root 根
const root = ReactDOM.createRoot(document.getElementById('root'))
// 在 root 根下挂载节点
root.render(
 <Provider store={store}>
   <App />
 </Provider>
)
  

引入react-redux包中的Provider组件(这个组件相当于是对Context中Provider的封装)和已定义好的redux中的store模块。

将App组件的渲染包裹在Provider组件渲染内部。

Provider组件的store属性保存需要在整个应用中全局共享的redux的store仓库。

在组件中链接store进行使用

要调用react-redux中的connect()函数组件中链接redux的store,connect()的两个参数主要用于将store中的state与dispatch()向组件的props属性注入,以便在包裹组件内部可以使用到store中的数据。

注意:connec()的返回值是一个HOC的函数

三大原则

单一数据源

整个应用的state被存储在object tree中,并且这个object tree只存在于唯一一个store中。

State是只读的

唯一改变state的方法就是触发action,action是一个用于描述已发生事件的普通对象。

使用纯函数来执行修改

为了描述action如何改变state tree ,你需要编写reducers。

异步Action

action creator

要将同步action创建函数与异步任务(比如网络请求)结合起来,标准的做法是使用redux thunk 中间件。 需要安装redux-thunk这个专门的库。

通过使用指定的middleware,action创建函数除了返回action对象外还可以返回函数

绑定库中的hooks

在react-redux绑定库中,可使用如下hooks实现功能:

  • useStore()-获取redux中store对象的引用
  • useDispatch()- 获取redux中store的dispatch API 方法引用
  • useSelect()-从redux的store中挑选应用中要使用到的state状态数据片段

immutable

  不可变更新所使用的库

在reducer()函数内部,如果使用深克隆对state状态数据进行克隆处理,性能开销可能会大增,facebook提出immutable-js库,这个库有更好的性能表现,可以使用immutable-js来实现reducer中state的处理。

immutable-js文档