redux_redux使用频率-程序员宅基地

redux

redux 基本介绍

redux 是一个状态机。这个是用来管理状态的。

这里要澄清一点, redux 并非 Facebook 推出的,而是由一个个人作者 Dan Abramov 所推出。

redux 和 react 的关系

两者之间本来没有任何关系,我们可以将 redux 用于 react、vue、angular 等技术,都可以用 redux,只不过 redux 和 react 配合得最好,一起出现的频率最多,所以之后在开发 react 应用的时候,自然而然就会想到使用 redux 来管理 react 应用的状态。

这因为这个原因,所以之后官方推出了 react-redux。

redux 的哲学

redux 中所涉及到的哲学有 3 个。

  1. single source of truth

翻译成中文叫做“单一真相”。所谓单一真相,使用一个 store 仓库来进行所有组件的状态管理。

  1. state is read-only

翻译成中文就是“状态只读”。store 里面的状态,我们只能读取,不可以(直接)修改。

在 redux 中,虽然不能直接修改仓库的状态,但是可以生成一份新的状态树,用新的状态树去覆盖旧的状态树。

  1. changes are made with pure function called reducer

如果要改变仓库的数据,需要使用纯函数来修改,这个纯函数在 redux 中被称之为 reducer。换而言之,就是使用 reducer 来修改仓库的数据。

接下来,简单介绍一下什么是纯函数。

纯函数是来自于函数式编程的概念。

编程范式:

  • 命令式编程:告诉计算机怎么做(How)
  • 声明式编程:告诉计算机我想要什么(What)

这两种编程范式中,一直是命令式发展的比较迅速。相比声明式,命令式编程要简单很多,简单易学。

命令式编程:

- 面向过程
- 面向对象

声明式编程:

- DSL(领域专用语言:CSS、SQL)
- 函数式编程(指的是数学里面的函数,没有变量)

纯函数:所谓纯函数,是指对于指定输入,返回指定输出,不存在副作用。

function test(x){
    
  return x + 1;
}
redux 的入门示例

首先,在正式介绍redux 之前,我们先书写一个 react 版本的计数器。

import React,{
    useState, useRef} from 'react'
function App() {
    

  let [count,setCount] = useState(0);
  let selRef = useRef();// 创建一个引用

  // 增加
  const increment = ()=>{
    
    // 1. 先获取下拉列表里面的值 2. count 增加
    let num = selRef.current.value * 1
    setCount(count + num);
  }

  // 减少
  const decrement = ()=>{
    
    // 1. 先获取下拉列表里面的值 2. count 增加
    let num = selRef.current.value * 1
    setCount(count - num);
  }

  // 奇数增加
  const incrementIfOdd = ()=>{
    
    if(count % 2 == 1){
    
      let num = selRef.current.value * 1
      setCount(count + num);
    }
   
  }

  // 异步增加
  const incrementAsync = ()=>{
    
    setTimeout(()=>{
    
      let num = selRef.current.value * 1
      setCount(count + num);
    },2000)
  }

  return (
    <div className="App">
      <p>你点击了 {
    count}</p>
      <select name="" id="" ref={
    selRef}>
        <option value="1">1</option>
        <option value="2">2</option>
        <option value="3">3</option>
      </select>
      <button onClick={
    increment}>+</button>
      <button onClick={
    decrement}>-</button>
      <button onClick={
    incrementIfOdd}>奇数增加</button>
      <button onClick={
    incrementAsync}>异步增加</button>
    </div>
  );
}

export default App;

观察上面的代码,我们发现,目前为止,没有只有 redux,组件内部自己维护了一组状态。

首先需要安装 redux:

npm i redux

接下来,在 src 下面新建 redux 目录,创建 4 个文件:

  • actions:描述状态如何进行修改,action 是一个对象。
  • actionType:action 的类型
  • reducers:纯函数,负责修改仓库的状态,之后 action 这个对象就会被派发到 reducer里面,从而生成新的状态树,去覆盖旧的状态树。
  • store:仓库,存储了所有组件的状态。

接下来书写 redux 版本,代码如下:

// actionType.js
// action 的类型
export const INCREMENT = 'increment'
export const DECREMENT = 'decrement'


// actions.js
// 描述状态如何修改,导出一系列的生成 action 对象的工厂函数
// action 是对象,对象用来描述如何对状态进行修改
// 导出两个方法,工厂函数,专门用于生成 action 对象的

import {
    INCREMENT,DECREMENT} from './actionType'
// action 里面书写了生成 action 对象的工厂函数
// 回头根据传入的 num 会返回一个 action 对象
// action 对象是对状态如何进行修改的一个描述
// 之后这个 action 会被派发到 reducer 里面
export const increment = (num)=>({
    
    type : INCREMENT,
    data : num
})

export const decrement = (num)=>({
    
    type : DECREMENT,
    data : num
})

// reducer.js
// reducer 是一个纯函数,接收两个参数,第一个是初始状态,第二个是 action 对象
import {
     INCREMENT,DECREMENT } from "./actionType";

// 这里我们导出了一个名为 counter 的函数,这个就是一个纯函数,也是 redux 里面称之为的 reducer
// 函数接收两个值,初始状态,action 对象
export default function counter(state=0, action){
    
    switch(action.type){
    
        case INCREMENT:
            return state + action.data
        case DECREMENT:
            return state - action.data
        default: return state;
    }
}

// store.js
// 仓库文件,调用 redux 里面有一个 createStore 的方法,接收一个 reducer 作为参数
// 这就是我们的仓库
import {
    createStore} from 'redux'
import counter from './reducers'

// 使用 createStore 方法创建仓库的时候
// 接收一个 reducer 作为参数
export default createStore(counter);

// index.js
// 将仓库挂载到根组件上面,监听 store 状态的变化,只要一变化,我们就要重新渲染
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import store from "./redux/store.js"; // 引入仓库
// 接下来需要将这个仓库挂在根组件上面

const render = ()=>{
    
  ReactDOM.render(
    <React.StrictMode>
      <App store={
    store}/>
    </React.StrictMode>,
    document.getElementById('root')
  );
}
render();

// 之后,只要仓库的状态发生变化,那么我们就应该重新渲染视图
store.subscribe(render);

// App.jsx
// 不再拥有自己的状态,状态从 store 里面获取。store.getState() 来获取状态
// 修改仓库状态:派发一个 action 到 reducer
props.store.dispatch(increment(num));
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_54105035/article/details/114239542

智能推荐

基于ONVIF协议的(IPC)客户端程序开发-1:测试工具(ONVIF Device Test Tool)-程序员宅基地

文章浏览阅读3.3k次,点赞2次,收藏7次。1、IPC地址 IPC摄像头默认的IP网段都是192.168.1.X,属于c类地址。其中A类,B类,C类网段各取了一部分:A类私有地址:10.0.0.0到10.255.255.255B类私有地址:172.16.0.0到172.31.255.255C类私有地址:192.168.0.0到192.168.255.2552、ONVIF Device Test Tool下载_onvif device test tool

什么是API测试_api调试是什么意思?-程序员宅基地

文章浏览阅读2.8k次。随着API在软件平台提供商中日益流行,为了确保应用程序之间能够正常通信,用户需要对API进行测试。虽然API测试的格式看起来像webhttp调用,但是执行的测试类型类似于其他应用程序的测试类型。API是一个应用程序调用另一个应用程序服务的一种方式。API可以提供企业软件调用之外的功能。例如天气、运动成绩、股市行情和许多其他类型的数据,都可以通过商业API获取。API通常使用代表性的状态传输(REST)接口。这使HTTP调用能够访问通用资源标识符(通常称为URI),该标识符执行对服务的调用。要测试AP_api调试是什么意思?

Homecoming CodeForces - 1315B(思维)-程序员宅基地

文章浏览阅读312次。After a long party Petya decided to return home, but he turned out to be at the opposite end of the town from his home. There are n crossroads in the line in the town, and there is either the bus or t..._homecoming codeforces

苹果录音功能在哪?iPhone自带录音功能的正确打开方式_苹果手机录音功能在哪-程序员宅基地

文章浏览阅读2w次。苹果手机的录音功能在哪?很多小伙伴平常会需要录音,但是在苹果手机中找不到这样的功能,如果你觉得苹果手机并没有这样的功能,那可是大错特错。在苹果手机里面,我们可以借助苹果手机的自带应用——语音备忘录进行录音。操作方法:1.打开苹果手机,在桌面应用中找到语音备忘录2.在界面上点击红色的按钮开始录音3.完成录音之后点击红色的按钮停止4.新录制完成的音频会自动保存在语音备忘录以iOS 1..._苹果手机录音功能在哪

基于VR技术的输电线路巡检仿真系统_vr 电力线路-程序员宅基地

文章浏览阅读1.5k次。基于VR技术,搭建电力输电仿真系统用于培训,提供用户沉浸式学习体验、交互式操作体验,VR设备能够提供沉浸式真实感的模拟场景,使得输电线路巡检内容视觉化,跨越了空间和时间的限制,有针对性的解决传统输电运检室对新员工培训的所遇到的困难.并且借助VR设备交互性特点,给学员提供误操作带来的严重后果的虚拟体验,目前高压电力设备的操作培训是基于实物进行的,不仅有较高的危险性,还不能辨别操作者是否规范操作。在输..._vr 电力线路

获取视频旋转角度,并对视频进行旋转_displaymatrix: rotation of -90.00 degrees-程序员宅基地

文章浏览阅读1.6w次。Android平台上录制视频时,如果是横屏录制(手机逆时针旋转90度),则录制的视频时不带角度的。如果是竖屏录制(正常的拿手机的姿势),此时的录制的视频的旋转角度是90度。如果再旋转90度,此时一般音量键和关屏键朝下,此时的视频的旋转角度是180。以此类推。所以在手机上的视频一般会有4中角度的视频,播放时,要对视频资源进行旋转后在进行播放。一般而言,带角度的视频和不带角度的视频,数据帧里面的宽_displaymatrix: rotation of -90.00 degrees

随便推点

使用 nodejs 快速搭建 MQTT 服务器及实时推送、获取数据_mqttnet.server 支持js客户端吗?-程序员宅基地

文章浏览阅读1w次,点赞11次,收藏68次。本文首发于个人网站,永久地址:https://iiter.cn/blogs/13 点进去给几个访问量也行啊github 仓库源代码:github文章目录MQTT 的概念和其他传输协议的区别MQTT 客户端的语言支持搭建基于 nodejs 的 MQTT 服务器创建服务端创建客户端推送创建客户端接收测试功能MQTT 的概念MQTT(Message Queue Telemetry Transp..._mqttnet.server 支持js客户端吗?

JAVA Switch-case 实例与用法_java switch case用法举例-程序员宅基地

文章浏览阅读3.8k次,点赞2次,收藏4次。在Java中有一个与if-else作用相似的东西,那就是switch-case。这就是Java中Switch-case语句的基本用法。要根据学生的成绩等级,判断学生的成绩范围。_java switch case用法举例

学生DIY计算机组装课程的重要性及意义-程序员宅基地

文章浏览阅读4k次。1 引言随着计算机应用的不断普及,学生动手组装计算机的热情也在不断高涨,兼容PC机以其价格低廉 (相对于品牌机)而深受在校大学生的喜爱,学生通过这门课程的学习,不仅能掌握计算机硬件的理论知识,更为自己能独立组装计算机(DIY)而对该课程产生了浓厚的兴趣。目前,很多高校开始把“计算机组装与维护”作为选修或开放实验课程来开设,其目的是为了培养学生的实践动手能力,掌握一技之长。由于现行的理论或实验教材,..._为什么要学计算机组装与维护

UE4学习笔记:关卡流(LevelStream)-程序员宅基地

文章浏览阅读1.4w次,点赞15次,收藏73次。通过关卡流可以在需要的时候动态加载关卡,不需要的时候卸载,降低内存使用率,构建大型场景。通过简单的示例了解关卡流的用法。1、新建一个两个关卡,在关卡里分别放一个"Level1"和"Level2"的文本,保存文件名为StreamLevel1和StreamLevel22、新建一个空关卡,并打开Levels窗口3、在Levels界面,将StreamLevel1和StreamLevel..._关卡流

【友云音】【问题排查记录-5】中间件启动异常_nc中间件一直打不开-程序员宅基地

文章浏览阅读1.1k次。问题现象NC中间件启动时一直卡在这个界面不进行加载。问题分析1、查看了ncSysconfig,发现了客户的jvm参数有一段异常。客户在部署的时候少填写了一段jar包。造成中间件启动异常。上面是正确写法,下面是异常填写。修改后启动正常。2、后续客户加上友云音的jvm参数后,发现中间件启动异常缓慢,之前启动中间件5min左右,现在启动了10min还在继续。于是查看了客..._nc中间件一直打不开

3dmax渲染卡光子、灯光缓存的处理方法-程序员宅基地

文章浏览阅读194次。有3dmax效果图渲染需求可以使用渲染100(注册填邀请码‘7788’可领券免费测试)检查灯光材质细分,全局细分,灯光缓存细分是否过高,如果参数过高,尝试调低参数渲染。可以试一下优化场景的工具,清理空物体、空代理、适当塌陷精简场景、清理场景垃圾等。、在vray全局开关勾选最大射线强度。通过隐藏或删除模型的方式逐步排查。、检查是否存在坡度渐变材质。、清理空物体等场景垃圾。

推荐文章

热门文章

相关标签