redux及react-redux

news2024/11/16 18:07:42

redux

这篇文章谈一谈仓库redux。

首先,学习任何东西都离不开官网。在此附上官网网址

Redux - A predictable state container for JavaScript apps. | Redux

1.什么是redux?

从如下几个方面:

redux在一个项目中可集中管理状态(数据)和逻辑代码,让你开发出强大的功能。

redux一般在中大型项目较为适用,小型项目建议使用订阅发布。

主要用于处理各个组件之间的通信问题。

2.使用redux的三大原则–规范

1.整个应用的数据state,只存放在唯一的store中。

2.state是只读的,唯一改变state数据的方法,是通过action自定义事件去修改。action是一个对象。通过Store.dispatch()去调用。

3.action自定义事件是需要通过纯函数的方式去触发的,因此需要编写与useReducer结构类似的函数去修改。reduce函数有两个参数:

参数一:上一次state的数据

参数二:传递过来的action

reduce函数要返回新的state数据。

3.原理过程分析:

在这里插入图片描述

初始化阶段:

仓库store-视图view(组件)

1.首先使用最顶层的reducer函数,创建redux-store。

​ createStore(callback)接受一个回调函数。这个回调函数就是最顶层的reducer函数

2.store调用一次reducer函数,并将返回值作为最新的state数据

3.与view框架交互,并将state数据渲染到UI视图层上面去,同时监听store的存在,以便知道state的更新

更新阶段

1.用户通过行为触发事件

2.通过store.dispatch()一个action给reducer进行state数据的处理。

3.此时数据虽然更改了,但有一个问题,没有触发视图的更新。有两种解决方案,一种是使用useState中的函数,还有一种就是重新渲染app组件。可能大家会认为非常损耗性能,但diff算法帮我们节省了性能

4.store 通知所有订阅过的 UI,通知它们 store 发生更新每个订阅过 store 数据的 UI 组件都会检查它们需要的 state 部分是否被更新。发现数据被更新的每个组件都强制使用新数据重新渲染,紧接着更新网页

4.使用

安装redux

npm i redux

然后就可以使用了


计数器小demo:

建立redux文件夹

store.js

import { createStore } from 'redux'
import { aa } from './reducers'
export default createStore(aa)

reducers.js

function aa(state = { num: 1 }, actions) {
    console.log(state, actions);
    let num = state.num
    switch (actions.type) {
        case "add":
            num = num + actions.data
            return { num }
        default:
            break;
    }
    return state
}
export {
    aa
}

index.js进行数据监听

// 操作dom
import ReactDOM from "react-dom/client";
// 引入App组件
import App from "./App"
// 引入css文件
import "./app.scss"
import store from "./redux/store"

import { BrowserRouter } from "react-router-dom"
// 设置挂载位置
const root = ReactDOM.createRoot(document.getElementById("root"))
root.render(
    <App />
)
store.subscribe(() => {
    root.render(
        <App />
    )
})

5.一个基础完整的redux实例代码

App.js

import React from 'react'
import store from "./redux/store"
import { createAdd, createDel } from './redux/action/createSum'
export default function App() {
    let { num } = store.getState()
    const handleAdd = () => {
        store.dispatch(createAdd())
    }
    const handleDel = () => {
        store.dispatch(createDel())
    }
    return (
        <div>
            <p>数据之{num}</p>
            <button onClick={handleAdd}>Add1</button>
            <button onClick={handleDel}>Del1</button>
        </div>
    )
}

redux/action/createSum.js

export const createAdd = () => {
    return { type: 'add', data: 1 }
}
export const createDel = () => {
    return { type: 'del', data: 1 }
}

redux/store.js

import { createStore } from 'redux'
import { aa } from './reducer/reducers'
export default createStore(aa)

redux/reducer/reducers.js

let init = { num: 1 }
function aa(state = init, actions) {
    console.log(state, actions);
    //由于纯函数的规范,返回是新的值
    let newState = { ...state }


    switch (actions.type) {
        case "add":
            newState.num = newState.num + actions.data
            return newState
        case "del":
            newState.num -= actions.data
        default:
            break;
    }
    return newState
}
export {
    aa
}

6.redux store里面处理异步

需要引入插件 redux-thunk

在store.js中引入

import { createStore, applyMiddleware } from 'redux'
import { aa } from './reducer/reducers'
import reduxThunk from 'redux-thunk'
export default createStore(aa, applyMiddleware(reduxThunk))

7.react-redux

小分类?

react-redux 旧版本 函数与class都通用

react-toolkit hooks版本,函数用的

什么是react-redux?

​ redux是一个独立的仓库,可以和市面上流行的框架例如Vue,angular,react等ui框架结合一起使用。如果我们要同时使用react和redux的时候,我们建议不要直接把react组件内容和store进行交互,而是应该将react-redux作为中间桥梁连接其中。

在这里插入图片描述

  1. 容器组件 包裹 UI组件 通过容器组件 与 redux进行操作
  2. 容器组件操作仓库 仓库数据给容器组件, 容器组件将数据给UI组件
  3. UI组件触发 容器组件发送action 给仓库进行修改数据

使用:

安装

npm i react-redux

初始版本:

components/SumUI

import React from 'react'
import store from "../redux/store"
import { createAdd, createDel, createAsync } from '../redux/action/createSum'
export default function SumUI(props) {
    console.log(props);
    let num = props.num
    const handleAdd = () => {
        props.handleAdd()
    }
    const handleDel = () => {
        props.handleDel()
    }
    const handleAsync = () => {
        props.handleAsync()
    }
    return (
        <div>
            <p>数据之{num}</p>
            <button onClick={handleAdd}>Add1</button>
            <button onClick={handleDel}>Del1</button>
            <button onClick={handleAsync}>异步加</button>
        </div>
    )
}

containner/Sum

import { connect } from 'react-redux'
import SumUI from '../component/SumUI'
import { createAdd, createDel, createAsync } from '../redux/action/createSum'
function mapStateToProps(state) {
    return state
}
const mapDispatchToProps = (dispatch) => {

    return {
        handleAdd: () => dispatch(createAdd()),
        handleDel: () => dispatch(createDel()),
        handleAsync: () => dispatch(createAsync())
    }
}
export default connect(mapStateToProps, mapDispatchToProps)(SumUI)

App.js

import React from 'react'
import Sum from './container/Sum'
import store from './redux/store'
export default function App() {
    return (
        <div>
            <Sum store={store}></Sum>
        </div>
    )
}

优化点:

1.mapStateToProps直接在connect里面写回调函数

2.mapDispatchToProps可以写成对象形式。系统会自动用dispatch包裹。

Sum.jsx优化

import { connect } from 'react-redux'
import SumUI from '../component/SumUI'
import { createAdd, createDel, createAsync } from '../redux/action/createSum'


export default connect(state => state, {
    handleAdd: createAdd,
    handleDel: createDel,
    handleAsync: createAsync
})(SumUI)

8.多组件之间通信

关键api:combineReducer

9.使用redux-devtools

如果要使用redux-devtools,我们需要使用第三方插件

安装 redux-devtools-extension,然后在store.js中配置

import {applyMiddleware, createStore,combineReducers} from "redux"
// 引入stroe异步中间件
import Thunk from "redux-thunk"
// 引入所有的纯函数reduce
import reduce from "./index"
// 使用插件查看数据
import {composeWithDevTools} from "redux-devtools-extension"
// 暴露仓库(store)
export default createStore(reduce,composeWithDevTools(applyMiddleware(Thunk)))

10.react-redux提供自定义的hooks

需要三个 redux react-redux @reduxjs/toolkit

1.创建store redux/store.js

// 开始准备创建仓库
import { configureStore } from '@reduxjs/toolkit';
// 引入纯函数
import reducerSum from "./reducers/reduceSum"


// 返回值就是仓库
const store = configureStore({
    // 每个组件的纯函数
    reducer:{
        reducerSum
    }
})



export default store

2.创建reducer纯函数 reducers/reduceSum.js

// 通过@reduxjs/toolkit创建纯函数
import {createSlice} from "@reduxjs/toolkit"

// 创建纯函数
const  reducerSum =  createSlice({
    name:"reducerSum",  // 名称
    initialState:{     // 初始数据 对象
        num:0,
        qwe:"大哥"
    },
    reducers:{          // 重新处理数据
        ADD:(state,action)=>{       // 数据加
            console.log(action);
            // state 代表数据原
            state.num = state.num +  action.payload
        },
        Reduce:(state,action)=>{
            state.num = state.num -  action.payload
        },
    }      
})

console.log(reducerSum,123);
export const {ADD,Reduce} = reducerSum.actions;  // 暴露行为给组件调用
export default reducerSum.reducer;  // 暴露reduce纯函数给仓库store

组件使用数据

import { useStore, useSelector, useDispatch } from "react-redux"
import { Reduce } from "../redux/reducers/reduceSum"


export default function Sum() {
    const store = useStore()
    console.log(store.getState().reducerSum.num,"useStore");

    const {num,qwe} = useSelector((state)=>state.reducerSum)
    console.log(num,"num");

    const dispatch = useDispatch()

    const handlAdd = ()=>{
        // dispatch({type: 'reducerSum/ADD',payload:1})
        // ADD(123)
        // dispatch(ADD(123)) 
    }

    const handlreduc = ()=>{
        dispatch(Reduce(10))
    }
  return (
    <div>
        <p>Sum--{store.getState().reducerSum.num}</p>
        <p>{num}--{qwe}</p>
        <button onClick={handlAdd}>点击夹</button>
        <button onClick={handlreduc}>点击减</button>

    </div>
  )
}

书写redux的规范

1.纯函数不要返回修改上一次的state数据,建议复制一下数据,然后进行修改,再进行返回数据

/ dispatch({type: ‘reducerSum/ADD’,payload:1})
// ADD(123)
// dispatch(ADD(123))
}

const handlreduc = ()=>{
    dispatch(Reduce(10))
}

return (


Sum–{store.getState().reducerSum.num}


{num}–{qwe}


点击夹
点击减

</div>

)
}






## 书写redux的规范

> 1.纯函数不要返回修改上一次的state数据,建议复制一下数据,然后进行修改,再进行返回数据
>
> 2.reducer不要执行任何异步操作,仅仅修改数据,赋值就好了。负责修改state数据

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

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

相关文章

【Pandas入门教程】如何操作文本数据

如何操作文本数据 来源&#xff1a;Pandas官网&#xff1a;https://pandas.pydata.org/docs/getting_started/intro_tutorials/index.html 笔记托管&#xff1a;https://gitee.com/DingJiaxiong/machine-learning-study 文章目录如何操作文本数据导包数据准备【小结】导包 imp…

怎么录屏?5 款免费无水印的录屏神器

无论您是想记录游戏中令人难忘的时刻、与他人分享视频教程&#xff0c;还是做更多类似的事情&#xff0c;都必须使用屏幕录像机。从 Internet 上很容易获得屏幕录像机&#xff1b;然而&#xff0c;找到一个“好”的并不是那么简单。当我们试用一些免费的屏幕录像机来捕捉电脑屏…

springboot整合之版本号统一管理

特别说明&#xff1a;本次项目整合基于idea进行的&#xff0c;如果使用Eclipse可能操作会略有不同&#xff0c;不过总的来说不影响。 springboot整合之如何选择版本及项目搭建 springboot整合之版本号统一管理 springboot整合mybatis-plusdurid数据库连接池 springboot整合…

华舞依旧,未来不远:智能光伏十大趋势告诉我们什么?

在“碳中和”时代&#xff0c;光伏正在日渐成为能源舞台的主角。我们知道&#xff0c;想要实现“碳中和”目标就需要降低能源带来的碳排放。而在能够实现这个目标的能源体系中&#xff0c;水电、风电受到环境限制较强&#xff0c;而氢能、核聚变为代表的下一代能源体系还不够成…

D59|单调栈进阶版

503.下一个更大元素II 1.题目 给定一个循环数组&#xff08;最后一个元素的下一个元素是数组的第一个元素&#xff09;&#xff0c;输出每个元素的下一个更大元素。数字 x 的下一个更大的元素是按数组遍历顺序&#xff0c;这个数字之后的第一个比它更大的数&#xff0c;这意味…

node.js+uni计算机毕设项目“宠到家”宠物领养小程序(程序+小程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程。欢迎交流 项目运行 环境配置&#xff1a; Node.js Vscode Mysql5.7 HBuilderXNavicat11VueExpress。 项目技术&#xff1a; Express框架 Node.js Vue 等等组成&#xff0c;B/S模式 Vscode管理前后端分离等…

“千万别奶睡,以后很难戒”,宝宝为啥喜欢奶睡,真有这么可怕?

我还记得懒妈妈哺乳的时候&#xff0c;身边有一个“过来人”提醒&#xff1a;不要奶睡&#xff0c;否则以后就戒不掉了&#xff0c;宝宝会一直吃着睡觉。事实上&#xff0c;当时懒惰的母亲更抗拒这种说法&#xff0c;主要原因是哄睡更困难&#xff0c;每天花更多的时间哄睡觉&a…

《C++程序设计原理与实践》笔记 第8章 函数相关的技术细节

在本章和下一章中&#xff0c;我们将注意力从程序设计转移到主要的编程工具——C语言上。我们会介绍一些语言的技术细节&#xff0c;来给出一个C的基本功能的稍宽的视角&#xff0c;并从更系统化的角度讨论这些功能。 8.1 技术细节 程序设计(programming)&#xff08;即如何用…

Podman QuickStart

Install Install Link brew install podman podman machine init podman machine startpodman machine init --cpus4 --disk-size64 --memory6144 podman machine start podman-machine-default开启和关闭root 权限 Tips: 切换root 模式前后&#xff0c;相互看不到对方模式下…

vue学习笔记(七)-vue3新特性

概念 vue3简介 2020年9月18日&#xff0c;Vue.js发布3.0版本&#xff0c;代号&#xff1a;One Piece&#xff08;海贼王&#xff09;耗时2年多、2600次提交、30个RFC、600次PR、99位贡献者github上的tags地址&#xff1a;https://github.com/vuejs/vue-next/releases/tag/v3.0…

C#实现QQ窗体功能

C#实现QQ窗体功能案例简述预备知识导图功能结构知识点分析C#基础知识Windows系统知识控件和组件案例简述 通过C#使用类似QQ窗体的功能&#xff0c;当窗体放置到屏幕的边缘&#xff0c;可以将窗体隐藏&#xff0c;当鼠标再次放置到屏幕边缘时&#xff0c;窗体可再次显示。 预备…

我的MEM管理类研究生,在路上

——生死看淡&#xff0c;不服就干。 一直怀揣着研究生梦的我&#xff0c;当年没能保研&#xff0c;也没能认真考研&#xff0c;在考取国家中级软件师证书后&#xff0c;意外发现了MEM&#xff08;Master of Engineering Management &#xff09;——工程管理硕士。 2021-11-…

Git - windows下操作 SSH Key

Git - windows下操作 SSH Key 流程 SSH密钥介绍 简单说&#xff0c;SSH是一种网络协议&#xff0c;用于计算机之间的加密登录。如果一个用户从本地计算机&#xff0c;使用SSH协议登录另一台远程计算机&#xff0c;我们就可以认为&#xff0c;这种登录是安全的&#xff0c;即使…

Nature:剑桥大学的研究人员找到了终结新冠的新药了吗?

本月初&#xff08;即2022年12月5日&#xff09;&#xff0c;《Nature》杂志发布了剑桥大学Teresa Brevini等人的一篇关于新冠研究的论文。在该论文中&#xff0c;作者首先发现法尼酯 X 受体&#xff08;FXR&#xff09;能够直接调节人体的ACE2的表达。过去的研究已经表明&…

手把手教你搭建Hexo博客

导读&#xff5c;很多开发者搭建自己的博客&#xff0c;会选择现有的博客系统方案&#xff0c;比如&#xff1a;Wordpress、Hexo和Halo等。其中Hexo博客作为全静态博客&#xff0c;没有数据库、对服务器资源消耗也极低&#xff0c;而且可定制化程度极高。本文将带领各位开发者基…

【Linux】编译的四个步骤

目录 平常的使用&#xff1a; 安装软件 编写&#xff1a;vi/vim vscode 编译 执行 路径/文件名 计算机五大部件 编译四步 1.预编译&#xff08;处理#&#xff09; 2.编译&#xff08;查错&#xff0c;代码到汇编&#xff09; 3.汇编(汇编到二进制指令) 4.链接 平常的…

157. 答读者疑问:为什么我的 manifest.json 文件无法正确被加载?

有教程的读者向我提问:已经完成了下列两个步骤的学习: SAP UI5 应用开发教程之十 - 什么是 SAP UI5 应用的描述符 DescriptorSAP UI5 应用开发教程之一百三十三 - SAP UI5 应用元数据文件 manifest.json 的加载和解析原理讲解自己本地 Visual Studio Code 开发了一个 SAP UI5…

SpringBoot+Mybatis-Plus+Thymeleaf+Bootstrap分页查询(前后端完整版开源学习)图书管理系统

目录分页主要逻辑&#xff0c;在3.7和3.81.准备工作1.1 参考博客1.2 项目结构2. 数据库3. 详细代码部分3.1 pom依赖3.2 application.yml3.3 BookMapper.xml3.4 BookMapper3.5 BookService 和 BookServiceImpl3.6 实体类entity book3.7控制层 BookController3.8 前端页面bookLis…

猿如意使用测评

本篇博客会记录使用猿如意这款产品的整体使用感受和相关建议&#xff0c;可以作为新人上手这款产品的参考 1. 猿如意的官方介绍 首先是官方对这款产品的介绍 猿如意是一款面向开发者的辅助开发工具箱&#xff0c;包含了效率工具、开发工具下载&#xff0c;教程文档&#xff0…

4.7 深入理解Spring

4.7.1 Spring 4.7.1.1 Spring模块 Spring 由七大模块组成&#xff0c;分别是 数据模块&#xff08;Data Access / Integration&#xff09;Web模块切面模块&#xff08;Aop&#xff0c;Aspects&#xff09;工具模块(Instrumentation)消息模块核心模块测试模块Spring模块4.7.…