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 可能包括服务器响应、缓存数据、本地生成尚未持久化到服务器的数据,也包括 UI 状态,如激活的路由,被选中的标签,是否显示加载动效或者分页器等等。

二、Redux的组成

2.1 store

store 就是保存数据的地方,整个应用只能有一个 store,可以理解为一个存储数据的仓库。

redux 提供 createStore 这个函数,用来创建一个store 以存放整个应用的 state:

import { createStore } from 'redux';
const store = createStore(reducer, [preloadedState], [enhancer]);

可以看到,createStore 接受 reducer初始 state(可选)和增强器(可选)作为参数,返回一个新的 store 对象.

2.2 state

state就是store 对象包含所有数据,如果要获取当前时刻的 state,可以通过 store.getState() 方法拿到:

import { createStore } from 'redux';
const store = createStore(reducer, [preloadedState], [enhancer]);
const state = store.getState();

2.3 action

  • state 的变化,会导致视图的变化。但是,用户接触不到 state,只能接触到视图。所以,state 的变化必须是由视图发起的。
  • action 就是视图发出的通知,通知store此时的 state 应该要发生变化了。
  • action 是一个对象。其中的 type属性是必须的,表示 action 的名称。其他属性可以自由设置,社区有一个规范可以参考:
const action = {
  type: 'ADD_TODO',
  payload: 'Learn Redux' // 可选属性 可自定义名称
};

所以action可以理解为视图层向store发送的一个命令(通知),它包含了需要执行的事件(type属性)以及传递的数据(自定义属性)。

2.4 reducer

  • store 收到 action 以后,必须给出一个新的 state,这样视图才会进行更新。state 的计算(更新)过程则是通过reducer 实现。
  • reducer 是一个函数,它接受 action 和当前 state 作为参数,返回一个新的 state:
const reducer = function (state = initState, action) {
  // ...
  return new_state;
};

创建store时,第一个参数就是reducer:

const store = createStore(reducer);

那么如何向store发送action呢?

store.dispatch({
  type: 'ADD_TODO',
  payload: 'Learn Redux'
});

store对象拥有dispath方法发送action,参数就是需要传递的action对象,然后reducer接收到action并处理,返回新的state,视图自动更新。

三、三大原则

Redux 可以用这三个基本原则来描述:

3.1 单一数据源

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

console.log(store.getState())
/* 输出
{
  visibilityFilter: 'SHOW_ALL',
  todos: [
    {
      text: 'Consider using Redux',
      completed: true,
    },
    {
      text: 'Keep all state in a single tree',
      completed: false
    }
  ]
}
*/

3.2 State只读

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

这样确保了视图和网络请求都不能直接修改 state,相反它们只能表达想要修改的意图。因为所有的修改都被集中化处理,且严格按照一个接一个的顺序执行,因此不用担心竞态条件(race condition)的出现。 Action 就是普通对象而已,因此它们可以被日志打印、序列化、储存、后期调试或测试时回放出来。

store.dispatch({
  type: 'COMPLETE_TODO',
  index: 1
})
store.dispatch({
  type: 'SET_VISIBILITY_FILTER',
  filter: 'SHOW_COMPLETED'
})

所以返回新的state时不能直接修改参数state,而是在不修改参数state的基础上返回新的state。

例如完成一个新增todo的功能:

case 'ADD_TODO':
      return state.push({
          text: action.text,
          completed: false
        })

这样是不会生效的,应为这样直接修改了state的值,正确的做法应该是:

 case 'ADD_TODO':
	    return [
	      ...state,
	      {
	        text: action.text,
	        completed: false
	      }
	    ]

这里使用了扩展运算符(…)将数组展开然后和新增的todo合并,对象同样可以使用扩展运算符达到新增属性的目的。

3.3 使用纯函数修改State

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

Reducer 只是一些纯函数,它接收先前的 stateaction,并返回新的 state。刚开始你可以只有一个 reducer,随着应用变大,你可以把它拆成多个小的 reducers,分别独立地操作 state tree 的不同部分,因为 reducer 只是函数,你可以控制它们被调用的顺序,传入附加数据,甚至编写可复用的 reducer 来处理一些通用任务,如分页器。

function visibilityFilter(state = 'SHOW_ALL', action) {
  switch (action.type) {
    case 'SET_VISIBILITY_FILTER':
      return action.filter
    default:
      return state
  }
}
function todos(state = [], action) {
  switch (action.type) {
    case 'ADD_TODO':
      return [
        ...state,
        {
          text: action.text,
          completed: false
        }
      ]
    case 'COMPLETE_TODO':
      return state.map((todo, index) => {
        if (index === action.index) {
          return Object.assign({}, todo, {
            completed: true
          })
        }
        return todo
      })
    default:
      return state
  }
}
import { combineReducers, createStore } from 'redux'
//合并reducer
let reducer = combineReducers({ visibilityFilter, todos })
//利用reducer创建store
let store = createStore(reducer)

四、基于Redux的TodoList

效果:

todes的reducer:

const initTodos = [
  {
    id: 1,
    text: "睡觉                        
(0)

相关推荐

  • 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

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

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

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

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

  • 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 状态管理工具优劣势示例分析

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

  • 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状态管理的三个规则总结

    目录 前言 No.1 一个关注点 No.2 提取复杂的状态逻辑 No.3 提取多个状态操作 总结 前言 React 组件内部的状态是在渲染过程之间保持不变的封装数据.useState() 是 React hook,负责管理功能组件内部的状态. 我喜欢 useState() ,它确实使状态处理变得非常容易.但是我经常遇到类似的问题: 我应该将组件的状态划分为小状态,还是保持复合状态? 如果状态管理变得复杂,我应该从组件中提取它吗?该怎么做? 如果 useState() 的用法是如此简单,那么什么时

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

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

  • Vue状态管理库Pinia详细介绍

    目录 什么是 Pinia 如何使用 Pinia 认识 Store 定义一个store 使用 store 操作 State Getters 1. 认识和定义 Getters 2. 访问 Getters 认识和定义 Action 什么是 Pinia Pinia (西班牙语中的菠萝),本质上依然是一个状态管理的库,用于跨组件.页面进行状态共享. pinia 与 vuex 的区别: 更友好的TypeScript支持,Vuex之前对TS的支持很不友好 与 Vuex 相比,Pinia 提供了一个更简单的 A

  • React createElement方法使用原理分析介绍

    目录 摘要 1.创建方法 2.处理type 3.处理config 4.处理children 5.对比真正的React.createElement源码 摘要 在上一篇说过,React创建元素有两种方式: 第一种是通过JSX方式创建,第二种是通过React.createElement方法创建.但是通过JSX创建React元素的方式,最终也会经过babel进行转换,再用React.createElement进行元素创建. 而这一篇文章,主要是讲一下React.createElement是如何创建Rea

  • vue store之状态管理模式的详细介绍

    状态管理 一.状态管理(vuex)简介 uex是专为vue.js应用程序开发的状态管理模式.它采用集中存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化.vuex也集成刀vue的官方调试工具devtools extension,提供了诸如零配置的time-travel调试.状态快照导入导出等高级调试功能. Vuex 的思想 当我们在页面上点击一个按钮,它会处发(dispatch)一个action, action 随后会执行(commit)一个mutation, mut

  • React各种状态管理器的解读及使用方法

    首先我们要先知道什么是状态管理器,这玩意是干啥的? 当我们在多个页面中使用到了相同的属性时就可以用到状态管理器,将这些状态存到外部的一个单独的文件中,不管在什么时候想使用都可以很方便的获取. react和vue有些不同,react没有自己专属的状态管理方式.它使用的其实是js相关的状态管理器.我们需要记住的是,视图可以引起状态的改变,而状态的改变会导致视图的二次渲染. 说了这么半天,那么我们在react中到底是怎样使用状态管理器的呢? redux闪亮登场 redux的前身技术是flux,他和fl

随机推荐