【React】redux和React-redux

news2025/1/11 15:04:21

🎀个人主页:努力学习前端知识的小羊
感谢你们的支持:收藏🎄 点赞🍬 加关注🪐

Redux和React-redux

  • redux
    • redux的使用
    • Redux的工作流
    • Redux API
      • store
      • action
      • reducer
      • store.dispatch()
      • redux的方法使用
  • React-Redux
    • 使用react-redux
    • provider
    • connect
    • 多个reducer
    • redux持久化
  • 总结

redux

redux的使用

redux适用于多交互、多数据源的场景。
使用redux的场景:

  1. 某个组件的状态需要共享
  2. 一个组件需要改变其他组件的状态时
  3. 一个组件需要改变全局的状态时

redux的三大原则:

  • 整个应用的 state 都被存储在一棵 object tree 中,并且 object tree 只存在于唯一的 store 中(这并不意味使用 redux 就需要将所有的 state 存到 redux 上,组件还是可以维护自身的 state )
  • state 是只读的。state 的变化,会导致视图(view)的变化。用户接触不到 state,只能接触到视图,唯一改变 state的方式则是在视图中触发actionaction是一个用于描述已发生事件的普通对象。
  • 使用 reducers 来执行 state 的更新。 reducers 是一个纯函数,它接受action和当前state作为参数,通过计算返回一个新的 state ,从而实现视图的更新。

Redux的工作流

在这里插入图片描述

  • 首先,用户在视图中通过store.dispatch方法发出action
  • 然后,store自动调用reducers,并且传入两个参数:当前state和收到的actionreducers会返回新的state
  • 最后,当store监听到state的变化,就会调用监听函数,触发视图的重新渲染

值得注意的是:Reducers不仅可以进行加工状态,还可以进行初始化状态(undefinded)

Redux API

store

  • store就是保存数据的地方,整个应用只能有一个store
  • redux提供createStore这个函数,用来创建一个store以存放整个应用的state
import { createStore } from "redux";
const store = createStore(reducer);

注:reducer是一个函数,是state操作的整合函数,每次修改state时都会触发该函数,他的返回值会成为新的state

action

  • state的变化,会导致视图的变化。但是,用户接触不到 state,只能接触到视图。所以,state 的变化必须是由视图发起的。
    - action 就是视图发出的通知,通知store此时的state应该要发生变化了。
  • action 是一个对象。其中的 type 属性是必须的,表示 action 的名称

定义一个名称为change-listaction,他所携带的数据信息是true

const action = {
                type:"change-list",
                payload:true       //可选属性
            }

reducer

  • store收action以后,必须给出一个新的state,视图才会进行更新。state的计算(更新)过程则是通过reducer实现
  • reducer是一个函数,他接受action和当前state作为参数,返回一个新的state
const reducer = function (state, action) {
  // ...
  return new_state;
};
  • 为了实现调用store.dispatch方法自动执行reducer函数,需要在创建store时将reducer传入createSore
import { createStore } from 'redux';
const reducer = function (state, action) {
  // ...
  return new_state;
};
const store = createStore(reducer);

上面代码中,createStore 方法接受reducer作为参数,生成一个新的 store。以后每当视图使用 store.dispatch 发送给 store 一个新的 action,就会自动调用 reducer函数,得到更新的 state

注: 这个 reducer 是一个纯函数。纯函数的意思是说,对于相同的输入,只会有相同的输出,不会影响外部的值,也不会被外部的值所影响。

store.dispatch()

store.dispatch是视图发出action的唯一方法,该方法接受一个action对象作为参数

import { createStore } from 'redux';
const store = createStore(reducer);

store.dispatch({
  type: 'ADD_TODO',
  payload: 'Learn Redux'  //可选属性
});

redux的方法使用

  1. 将reducer传递进createStore后,我们会得到一个store对象:
const store = Redux.createStore(countReducer);
  1. store对象创建后,对state的所有操作都需要通过它来进行:
  • 读取state:
store.getState()
  • 修改state:
store.dispatch({type:'ADD'})
  1. store还拥有一个subscribe方法,这个方法用来订阅state变化的信息
store.subscribe(()=>{
    // store中state发生变化时触发
    console.log('state变化了')
    console.log(store.getState())
});

总结:
Redux中最最核心的东西就是这个store,只要拿到了这个store对象就相当于拿到了Redux中存储的数据。在加上Redux的核心思想中有一条叫做“单一数据源”,也就是所有的state都会存储到一课对象树中,并且这个对象树会存储到一个store中。所以到了React中,组件只需获取到store即可获取到Redux中存储的所有state。

React-Redux

在前面我们使用redux,面对着组件无法状态无法公用,每一个状态组件都需要通过订阅来监视,状态更新会影响到全部组件更新等问题,React 官方在 redux 基础上提出了 React-Redux 库。

使用react-redux

  • 安装react-redux
npm install -i react-redux
  • 创建reducer
const TabbarReducer = (prevState={
    show:true
},action)=>{
    let newState = {...prevState}
    switch (action.type) {
        case "kerwinhide-tabbar":
            newState.show = false
            return newState;
        case "kerwinshow-tabbar":
            newState.show = true
            return newState;
        default:
            return prevState
       
    }
}
  • 创建store
const store = createStore(reducer);

provider

由于我们的状态可能会被很多组件使用,所以 React-Redux 给我们提供了一个 Provider 组件,可以全局注入 redux 中的 store ,只需要把 Provider 注册在根部组件即可

ReactDOM.createRoot(document.getElementById('root')).render(
  <Provider store={store}>
    <App />
  </Provider>
)

connect

react-redux提供connect方法,用于从UI组件生成容器组件。connect的意思,就是将这两种组件连起来

import getCinemaListAction from '../redux/actionCreator/getCinemaListAction'
import { connect } from 'react-redux'
function Cinemas(props){
// .....
}
const mapDispatchToprops = {
  getCinemaListAction
}
const mapStateToProps = (state)=>{
  return {
    list:state.CinemaListReducer.list,
    cityname:state.Cityreducer.cityname
  }
}
export default connect(mapStateToProps,mapDispatchToprops)(Cinemas)

多个reducer

Redux中是允许我们创建多个reducer的,我们可以根据它的数据和功能进行拆分,拆分后,还需要使用Redux为我们提供的函数combineReducer将多个reducer进行合并,合并后才能传递进createStore来创建store

const reducer = combineReducers({
    stuReducer,
    schoolReducer
});

const store = createStore(reducer);

读取数据时,直接通过state.stuReducerstate.schoolReducer读取数据

redux持久化

import {persistStore,persistReducer} from 'redux-persist'
import storage from 'redux-persist/lib/storage'

const persistConfig = {
    key:"kerwin",
    storage,
}

const reducer = combineReducers({
    Cityreducer,
    TabbarReducer,
    CinemaListReducer
})
//改造reducer
const persistedReducer =persistReducer(persistConfig,reducer)


const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;

const store = createStore(persistedReducer,composeEnhancers
    (applyMiddleware(reduxThunk,reduxPromise)));
    
//改造store
let persistor = persistStore(store)

export {store,persistor}


改造根组件

import { Provider } from "react-redux";
import  {store,persistor} from "./06-react-redux/redux/store";
import { PersistGate } from "redux-persist/integration/react";

ReactDOM.render(
    <Provider store={store}>
        <PersistGate loading={null} persistor={persistor}>
            <App />
        </PersistGate>
     </Provider>
,document.getElementById('root'))

总结

数据流更新动画

  • Redux 是一个管理全局应用状态的库
    • Redux 通常与 React-Redux 库一起使用,把 Redux 和 React 集成在一起
  • Redux 使用 “单向数据流”
    • State 描述了应用程序在某个时间点的状态,视图基于该 state 渲染
    • 当应用程序中发生某些事情时:
      • 视图 dispatch 一个 action
      • store 调用 reducer,随后根据发生的事情来更新 state
      • store 将 state 发生了变化的情况通知 UI
    • 视图基于新 state 重新渲染
  • Redux 有这几种类型的代码
    • Action 是有 type 字段的纯对象,描述发生了什么
    • Reducer 是纯函数,基于先前的 state 和 action 来计算新的 state
    • 每当 dispatch 一个 action 后,store 就会调用 root reducer

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/482468.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

python人工智能【隔空手势控制鼠标】“解放双手“

大家好&#xff0c;我是csdn的博主&#xff1a;lqj_本人 这是我的个人博客主页&#xff1a; lqj_本人的博客_CSDN博客-微信小程序,前端,python领域博主lqj_本人擅长微信小程序,前端,python,等方面的知识https://blog.csdn.net/lbcyllqj?spm1011.2415.3001.5343哔哩哔哩欢迎关注…

【计算机图形学基础教程】MFC上机操作步骤

MFC上机操作步骤 步骤1 在Visual Studio界面&#xff0c;选择文件-新建-项目&#xff1a; 步骤2 在新建项目对话框&#xff0c;选择MFC-MFC应用程序&#xff1a; 步骤3 创建一个带有下列特征的新控制台工程框架&#xff0c;主要内容如下&#xff1a; 基于Win32的单文档…

PMP/高项 05-项目进度管理

项目进度管理 概念 项目进度管理&#xff08;Schedule Management) 项目进度管理又叫项目工期管理&#xff08;Duration Management)或项目的时间管理(Time Management) 是一种为管理项目按时完成项目所需的各个过程 进度管理过程 规划进度管理 定义活动 排列活动顺序 估算活…

前端web3入门脚本五:decode input data

一、前言 作为一个前端&#xff0c;在调用合约调试的时候&#xff0c;在区块浏览器里拿到一串 hex 格式的 input data&#xff0c;我们应该怎么decode呢&#xff1f; 二、举例 解码交易需要拥有 对应合约的 abi 以及 input data 下面举例介绍怎么获得这两个信息&#xff1a; 参…

二叉搜索树中的众数

1题目 给你一个含重复值的二叉搜索树&#xff08;BST&#xff09;的根节点 root &#xff0c;找出并返回 BST 中的所有 众数&#xff08;即&#xff0c;出现频率最高的元素&#xff09;。 如果树中有不止一个众数&#xff0c;可以按 任意顺序 返回。 假定 BST 满足如下定义&…

存储资源调优技术——智能缓存分区

SmartPratition智能缓存分区 基本概念 本质上就是一种Cache分区技术 通过对系统核心资源的分区&#xff08;隔离不同业务所需要的缓存资源&#xff09;&#xff0c;保证关键应用的性能 工作原理 用户可以以LUN或文件系统为单位设置SmartPartition分区 每个SmartPartition分区的…

Qt文件系统源码分析—第二篇QSaveFile

范围 深度 首先指定深度分析深度&#xff0c;否者会陷入代码海洋之中。 本文只分析到Win32 API/Windows Com组件/STL库函数层次&#xff0c;再下层代码不做探究 本文主要了解QSaveFile及其具体实现&#xff0c;使用到父类数据的地方只讨论关键点 QT Private类 大部分Qt类有…

基础篇-设计模式

单例模式&#xff1a; 注意&#xff1a;这里的唯一实例不是使用时候才创建,而是构造时候就会创建; 注意&#xff1a;提前创建了对象&#xff0c;并不是调用时候才创建 解决方法&#xff1a; 枚举饿汉单例&#xff1a; 注意: 饿汉式枚举不会通过反序列化破坏单例 懒汉模式&…

SQL笔记(3)——MySQL数据类型

学习MySQL&#xff0c;通常应该是先学习数据类型的&#xff0c;因为不管是开发还是MySQL中&#xff0c;每个数据对象都有其对应的数据类型&#xff0c;MySQL提供了丰富的数据类型&#xff0c;如在创建表的时候就需要指定列的数据类型&#xff0c;在向表中插入数据时&#xff0c…

ElasticSearch(一)下载及安装(windows)

1. 官网 ElasticSearch官网地址ElasticSearch生态组件下载地址Kibana下载地址ik中文分词插件 备注&#xff1a;网址打不开&#xff0c;或者打开速度慢是正常情况。 2. 解压后目录结构 bin &#xff1a;脚本文件&#xff0c;包括启动elasticsearch&#xff0c;安装插件&#…

目录打开显示提示文件或目录损坏且无法读取、文件或目录损坏且无法读取的破解之道

咱们在平日工作时&#xff0c;通常都会将资料放进不同的目录中&#xff0c;方便咱们找到&#xff0c;随着时间的推移就会产生有越来越多目录。最近有位用户了这样一个问题&#xff0c;就是目录无论怎么都无法打开&#xff0c;这样就无法浏览、使用里面的资料了&#xff0c;影响…

springboot sharding-jdbc 主从 读写分离

目录 1 mysql 主从搭建 1.1 docker mysql 主从搭建 1.2 非docker mysql 主从搭建 2 springboot sharding-jdbc 主从 读写分离 2.1 pom 加依赖 2.1 yml 配置文件 3 测试 -> 直接使用 就是读写分离 3.1 实体类User -> 数据字段 对象字典 3.2 Mapper -> 增删改查…

Nomogram | 盘点一下绘制列线图的几个R包!~(二)

1写在前面 不知道各位小伙伴的五一假期过的在怎么样&#xff0c;可怜的我感冒了。&#x1f637; 今天继续之前没有写完的列线图教程吧&#xff0c;再介绍几个制作列线图的R包。&#x1f920; 2用到的包 rm(list ls())library(tidyverse)library(survival)library(rms)library(…

新闻文本关键词提取有哪些算法,这些算法的特点以及应用,以及不足方面的解决办法

目录 一、新闻文本关键词提取算法 1. TF-IDF&#xff08;Term Frequency-Inverse Document Frequency&#xff09;算法 2. TextRank算法 3. 词向量算法 4. 深度学习算法 5. 主题模型算法 二、这些算法的不足方面的解决办法 1. TF-IDF算法&#xff1a; 2. TextRank算法&…

一文彻底读懂nginx中的location指令

Nginx主配置文件结构 location 介绍 location是Nginx中的块级指令(block directive),&#xff0c;location指令的功能是用来匹配不同的url请求&#xff0c;进而对请求做不同的处理和响应&#xff0c;这其中较难理解的是多个location的匹配顺序&#xff0c;本文会作为重点来解释…

Effective Modern C++

模板类型推导 template<typename T> void f(T& parms);//reference template<typename T> void f(const T& parms);//const ref template<typename T> void f(T* parms);//pointer template<typename T> void f(T&& parms);//univers…

通讯录的实现(动态完结版)

&#x1f349;博客主页&#xff1a;阿博历练记 &#x1f4d6;文章专栏&#xff1a;c语言&#xff08;初阶与进阶&#xff09; &#x1f357;代码仓库&#xff1a;阿博编程日记 &#x1f339;欢迎关注&#xff1a;欢迎友友们点赞收藏关注哦 文章目录 &#x1f354;前言&#x1f…

java 倒计时实现的方式

倒计时的实现方法有很多种&#xff0c;本文给大家介绍其中一种&#xff0c;最简单的一种实现方式&#xff0c;也是最方便的一种方式&#xff0c;希望能帮到大家。 1、 java中倒计时是利用循环来实现的&#xff0c;我们可以使用循环语句来实现。 2、 java中使用 bool类的 setTim…

python相对路径与绝对路径

9.1 Python 绝对路径与相对路径 - 知乎 (zhihu.com) 目录 1. 绝对路径 1.1 概念 1.2 用绝对路径打开文件 1.2 相对路径 1.3 python路径表示的斜杠问题 1. 绝对路径 1.1 概念 绝对路径 指完整的描述文件位置的路径。绝对路径就是文件或文件夹在硬盘上的完整路径。 在 Win…

Spring--AOP详细介绍--和详细代码演示证明理解

目录 Spring--AOP详细介绍 基本介绍 代码演示—入门 需求说明 定义一个接口类Vehicle 定义一个实现接口类的Car类 定义一个实现接口类的Ship类 创建测试类Test.java 来思考一下&#xff0c; 解决方案-动态代理方式-2 修改 Car类 修改 Ship类 创建VehicleProxyProvid…