React状态管理Redux的使用介绍详解

目录
  • 1. 简介
  • 2. 核心概念
  • 3. redux工作流
  • 4. 模拟redux工作流程
  • 5. 使用redux
  • 6. react-redux

1. 简介

Redux 是 JavaScript 应用的状态容器(对象),提供可预测的状态管理。可以让你开发出行为稳定可预测的应用,运行于不同的环境(客户端、服务器、原生应用),并且易于测试。Redux 除了和 React 一起用外,还支持其它界面库。

解决的问题:多层级组件间通信问题。

2. 核心概念

单一数据源

整个redux中的数据都是集中管理,存储于同一个数据源中,数据源中的数据为单向数据流,不可直接修改。

纯函数 (reducer) 统一对 state 数据修改

redux 定义了一个 reducer 函数来完成 state 数据的修改,reducer 会接收先前的 state 和 action,并返回新的 state。

  • 函数执行结果是可预期的(多次调用结果相同)
  • 函数执行不会触发副作用
  • 函数中的变量,没有使用外部的

3. redux工作流

①、store通过 reducer 创建了初始状态

②、component 通过 store.getState() 获取到了 store 中保存的 state 挂载在了自己的状态上

③、用户产生了操作,调用了 actions 的方法

④、actions 的方法被调用,创建了带有标示性信息的 action(描述对象)

⑤、actions 将 action 通过调用 store.dispatch 方法发送到了 reducer 中

⑥、reducer 接收到 action 并根据标识信息判断之后返回了新的 state

⑦、store 的 state 被 reducer 更改为新 state 的时候,store.subscribe 方法里的回调函数会执行,此时就可以通知 component 去重新获取 state

4. 模拟redux工作流程

redux.js:

// 自定义的redux状态管理
// 用 createStore 方法接收 reducer 纯函数
export const createStore = reducer => {
    // 接收新的带有单一数据源的对象
    let state = undefined
    // 订阅队列
    let tasks = []
    // 3.store.dispatch({type,payload})
    const dispath = action => {
        // 将 action 交给 reducer ,返回一个新的数据源
        state = reducer(state, action)
        // 数据源发生变化时,让订阅队列中的每一个回调函数执行
        tasks.forEach(cb => cb())
    }
    const subscribe = cb => {
        // 把回调函数放入订阅队列中
        tasks.push(cb)
        // 取消订阅时,删除订阅队列中的回调函数
        return () => tasks.splice(tasks.indexOf(cb), 1)
    }
    // 返回数据源
    const getState = () => state
    // 2.初始化,防止组件第一次调用 getState 得到的是 undefined
    dispath({ type: '@@init@@' })
    // 返回 redux 工作流中需要的三个函数
    return {
        dispath,
        subscribe,
        getState
    }
}

index.js:

// 导入仓库
import { createStore } from './redux'
// 5.设置一个初始值
const initState = {
    num: 100
}
// 4.创建 reducer 纯函数
const reducer = (state = initState, action) => {
    // 完成组件中加的操作
    if (action.type === 'add') return { ...state, num: state.num + action.payload }
    return state;
}
const store = createStore(reducer)
export default store

App.jsx:

import React, { Component } from 'react'
// 组件中导入仓库
import store from './store'
class App extends Component {
  componentDidMount() {
    // 订阅 redux 的频道,只要频道发生更改,就会触发视图更新
    // 并且让 unsubscribe 接收到 redux 中取消订阅的函数
    this.unsubscribe = store.subscribe(() => this.forceUpdate())
  }
  componentWillUnmount() {
    // 取消订阅,组件卸载时执行
    this.unsubscribe()
  }
  render() {
    return (
      <div>
        {/* 1.组件通过 getState 得到数据 */}
        <h3>{store.getState().num}</h3>
        <hr />
        <button
          onClick={() => {
            // 动作:添加;数据:每次加2
            store.dispath({ type: 'add', payload: 2 })
          }}
        >
          ++++
        </button>
      </div>
    )
  }
}
export default App

5. 使用redux

安装 redux:

redux 没有内嵌在 react 框架中,使用时需要手动去安装:yarn add redux

安装 redux-devtools:

安装第3方模块,让调试工具显示 state:

# yarn add -D @redux-devtools/extension
import { composeWithDevTools } from '@redux-devtools/extension'
const store = createStore(
  reducer,
  composeWithDevTools()
);

把上述案例,用真实的 redux 实现一下:

index.js:

// 1.导入redux中的createStore创建仓库数据的方法
import { createStore } from 'redux'
// 配合浏览器安装的插件来进行redux调试所用
// 开发时有用,生产要关闭
import { composeWithDevTools } from '@redux-devtools/extension'
// 2.初始state数据
const initState = {
  num: 100
}
// 3.定义一个纯函数reducer,专门用来操作state中的数据,要返回一个新的state
const reducer = (state = initState, action) => {
  if (action.type === 'add') return { ...state, num: state.num + action.payload }
  return state;
}
// 得到数据对象
let store
// 开发与生产环境的判断,提高安全性
process.env.NODE_ENV === 'development'
  ?
  store = createStore(
    reducer,
    composeWithDevTools()
  )
  :
  store = createStore(
    reducer
  )
// 导出
export default store

6. react-redux

概述:

React-Redux 是 Redux 的官方针对 React 开发的扩展库,默认没有在 React 项目中安装,需要手动来安装。react-redux 是依赖于 redux,所以你必须安装 redux。

你可以理解为 react-redux 就是 redux 给我们提供一些高阶组件,能解决的问题是:使用它以后我们不需要在每个组件中再去手动订阅数据的更新了,方便了 react 组件中调用 redux 中的数据。

安装:

yarn add react-redux

使用步骤:

在程序主文件 index.js 文件中,定义 Provider。此处类似于之前跨组件通信处的 Provider 一样,旨在让全局的组件共享 store 中的数据。

import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'
// 导入Provider生产数据者组件
import { Provider } from 'react-redux'
// 导入数据源
import store from './store'
ReactDOM.render(
  // 包裹所有的路由
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
)

在组件中使用 react-redux

import React, { Component } from 'react'
// 提供一个高阶组件 connect 用来把 redux 中的 state 和 action 映射到当前组件的 props 中
import { connect } from 'react-redux'
// 此函数必须要返回一个json对象
// 函数的 state 参数就是 redux 中的 state 数据
const mapStateToProps = state => {
  return { num: state.num }
}
// mapStateToProps 函数的两种简写写法
// const mapStateToProps = state => state
// @connect(state => state, mapDispatchToProps)
// 此函数必须要返回一个json对象
// dispatch 就是之前通过 store.dispatch 的方法
const mapDispatchToProps = dispatch => {
  return {
    add(n = 1) {
      // 动作:增加,数据:n
      dispatch({ type: 'add', payload: n })
    }
  }
}
// 函数的方式可以同步也可以异步,dispatch 是你手动在需要的地方来调用
// const mapDispatchToProps = dispatch => {
//   return {
//     add(n = 1) {
//       setTimeout(() => {
//         dispatch({ type: 'add', payload: n })
//       }, 1000)
//     }
//   }
// }
// 该函数的对象写法:
// 如果为对象方式则只能使用同步,不能用异步,因为在 connect 实现时如果是对象,则它会主动调用 dispatch
// 调用了 dispatch 它就立刻执行。而如果是一个异步,则就会不符合 dispatch 要求,则报错
// const mapDispatchToProps = {
//   add: (n = 1) => ({ type: 'add', payload: n })
// }
// 参数1:函数,把 redux 中的 state 数据映射到当前的 props 属性中
// 参数2:函数|对象,把你操作的 dispatch 方法映射到当前的 props 属性中
@connect(mapStateToProps, mapDispatchToProps)
class App extends Component {
  render() {
    console.log('props', this.props)
    return (
      <div>
        <h3>{this.props.num}</h3>
        <hr />
        <button onClick={() => this.props.add()}>++++</button>
      </div>
    )
  }
}
export default App

上面是使用装饰器的写法,还有不使用装饰器的写法:

我们需要将装饰器一行注释,并且修改导出方式。

到此这篇关于React状态管理Redux的使用介绍详解的文章就介绍到这了,更多相关React Redux内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • react18中react-redux状态管理的实现

    react的状态管理还是挺多的现在流行的有以下五种: Recoil MobX XState Redux Context 今天我们来讲一下react众多状态管理之一的redux,虽然这个我不太喜欢用,但是我觉得简单的状态管理谁都会,但是难的就是程序员的分水岭,所以今天来给大家讲一下redux. 下面我们来讲讲redux的优点: 可以在众多组件中传值,突破react单向数据流的限制 不仅支持react还支持vue等主流框架 当然是好用方便啦 接下来我们讲一下啥时候去使用他 在我们有好多组件,但是组件

  • react-redux集中式状态管理及基本使用与优化

    目录 1.react-redux 2.连接容器组件与UI组件 3.react-redux基本使用 优化1.简写mapState和mapDispatch两个映射方法 优化2.Provider组件的使用 优化3.整合UI组件与容器组件 优化总结 1.react-redux react-redux把组件分为两类,一类叫做UI组件,一类叫做容器组件: UI组件的外侧都要包裹一个容器组件. 注意️:本文使用的示例为之前的文章中的示例.在之前的文章中已经做过了介绍,在本文就不再阐述. 建议阅读顺序是:[re

  • React状态管理Redux原理与介绍

    目录 一.Redux 二.Redux的组成 2.1 store 2.2 state 2.3 action 2.4 reducer 三.三大原则 3.1 单一数据源 3.2 State只读 3.3 使用纯函数修改State 四.基于Redux的TodoList 五.react-redux 5.1 connect方法 5.2 Provider组件 一.Redux 和vuex一样,redux的出现是为了管理web应用的公共状态. 这些 state 可能包括服务器响应.缓存数据.本地生成尚未持久化到服务

  • React状态管理Redux的使用介绍详解

    目录 1. 简介 2. 核心概念 3. redux工作流 4. 模拟redux工作流程 5. 使用redux 6. react-redux 1. 简介 Redux 是 JavaScript 应用的状态容器(对象),提供可预测的状态管理.可以让你开发出行为稳定可预测的应用,运行于不同的环境(客户端.服务器.原生应用),并且易于测试.Redux 除了和 React 一起用外,还支持其它界面库. 解决的问题:多层级组件间通信问题. 2. 核心概念 单一数据源 整个redux中的数据都是集中管理,存储于

  • React状态管理器Rematch的使用详解

    目录 Rematch使用 1. Rematch介绍 2. Rematch特性 3. 基本使用 Rematch使用 1. Rematch介绍 Rematch是没有样板文件的Redux的最佳实践,没有action types. action creators, 状态转换或thunks. 2. Rematch特性 Redux 是一个了不起的状态管理工具,由良好的中间件生态系统和优秀的开发工具支持.Rematch 以 Redux 为基础,减少样板文件并强制执行最佳实践. 小于 2kb 的大小 无需配置

  • React immer与Redux Toolkit使用教程详解

    目录 1. immer 1.1 setState结合immer使用 1.2 useState结合immer使用 1.3 immer和redux集合 2. Redux Toolkit 1. immer 概述: 它和immutable相似的,实现了操作对象的数据共享,可以优化性能.它实现的原理使用es6的Proxy完成的.小巧,没有像immutable哪样有新数据类型,而是使用js类型. 安装: yarn add immer@9 1.1 setState结合immer使用 简单使用: import

  • Flutter状态管理Provider的使用示例详解

    目录 前言 计数器 全局状态 总结 前言 Provider是三大主流状态管理框架官方推荐使用的框架,它是基于官方数据共享组件InheritedWidget实现的,通过数据改变调用生命周期中的didChangeDependencies()方法,来实现状态的通知改变. InheritedWidget的使用可以参考我之前的这篇Flutter中几种数据传递的应用总结. 计数器 还是以计数器为例,这次通过Provider实现,provider相较于bloc并没有那么强制性分层,所以这里我们自己分为数据层(

  • Vue.js状态管理之Pinia与Vuex详解

    目录 前言 Pinia 和 Vuex 简介 什么是Pinia? 什么是 Vuex? Pinia 的特点 模块化设计 完整的开发工具支持 Pinia 很直观 Pinia 是可扩展的 TypeScript 支持 Pinia 轻量的 Vuex的特点 模块 开发工具支持 热重载 TypeScript 支持 Pinia和Vuex的代码对比 Pinia 和 Vuex 的优缺点 Pinia 的优点 Pinia 的缺点 Vuex 的优点 Vuex 的缺点 我应该使用哪个:Pinia 还是 Vuex? 结论 前言

  • React开发进阶redux saga使用原理详解

    目录 前言 redux的特点 分析原理 1. 自动执行Generator 2. 发布订阅模式 3. put, takeEvery, delay, call返回effect 总结 前言 工作中使用了redux-saga这个redux中间件,如果不明白内部原理使用起来会让人摸不着头脑,阅读源码后特意对其原理做下总结. redux的特点 一个标准.管理应用副作用的redux中间件 实现切面编程方式 声明式的编写方式 订阅发布的设计模式 优点: 把异步操作转移到单独 saga文件中,而不是糅杂在acti

  • 更强大的React 状态管理库Zustand使用详解

    目录 介绍 创建项目项目 安装项目依赖 创建项目结构 设置环境变量 服务 设置 store 清除/重置存储 介绍 在这篇文章中,我会介绍 Zustand 在实际项目中的使用. 我会构建一个 GitHub 用户搜索项目,在项目中通过调用 GitHub API 来实现搜索用户的功能.我还会并演示如何直接从 Zustand 存储中进行 API 调用,并将状态持久化到 sessionStorage 或 localStorage 中. 完成效果如下: 创建项目项目 首先,我们需要创建一个新的 React

  • React redux 原理及使用详解

    目录 概述 createStore创建store applyMiddleware 应用中间件 combineReducers 合并多个reducer dispatch 中间件 中间件的调用顺序 store redux 数据流 bindActionCreators compose enhancer 使用 redux 常遇见的问题 概述 一个状态管理工具 Store:保存数据的地方,你可以把它看成一个容器,整个应用只能有一个 Store. State:包含所有数据,如果想得到某个时点的数据,就要对

  • React 状态管理工具优劣势示例分析

    目录 什么是状态管理? React 状态管理方案 方案介绍 方案对比 Source 相关建议 什么是状态管理? “状态”是描述应用程序当前行为的任何数据.这可能包括诸如“从服务器获取的对象列表”.“当前选择的项目”.“当前登录用户的名称”和“此模式是否打开?”等值. 众所周知,我们在研发一个复杂应用的过程中,一套好的状态管理方案是必不可少的,既能提升研发效率,又能降低研发维护成本,那么状态管理方案那么多,它们有什么不同,我们又该如何选择适合当前应用的方案呢? 本期将主要就 react 的常用状态

随机推荐