redux 是一个状态机。这个是用来管理状态的。
这里要澄清一点, redux 并非 Facebook 推出的,而是由一个个人作者 Dan Abramov 所推出。
两者之间本来没有任何关系,我们可以将 redux 用于 react、vue、angular 等技术,都可以用 redux,只不过 redux 和 react 配合得最好,一起出现的频率最多,所以之后在开发 react 应用的时候,自然而然就会想到使用 redux 来管理 react 应用的状态。
这因为这个原因,所以之后官方推出了 react-redux。
redux 中所涉及到的哲学有 3 个。
翻译成中文叫做“单一真相”。所谓单一真相,使用一个 store 仓库来进行所有组件的状态管理。
翻译成中文就是“状态只读”。store 里面的状态,我们只能读取,不可以(直接)修改。
在 redux 中,虽然不能直接修改仓库的状态,但是可以生成一份新的状态树,用新的状态树去覆盖旧的状态树。
如果要改变仓库的数据,需要使用纯函数来修改,这个纯函数在 redux 中被称之为 reducer。换而言之,就是使用 reducer 来修改仓库的数据。
接下来,简单介绍一下什么是纯函数。
纯函数是来自于函数式编程的概念。
编程范式:
这两种编程范式中,一直是命令式发展的比较迅速。相比声明式,命令式编程要简单很多,简单易学。
命令式编程:
- 面向过程
- 面向对象
声明式编程:
- DSL(领域专用语言:CSS、SQL)
- 函数式编程(指的是数学里面的函数,没有变量)
纯函数:所谓纯函数,是指对于指定输入,返回指定输出,不存在副作用。
function test(x){
return x + 1;
}
首先,在正式介绍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 个文件:
接下来书写 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));
文章浏览阅读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
文章浏览阅读2.8k次。随着API在软件平台提供商中日益流行,为了确保应用程序之间能够正常通信,用户需要对API进行测试。虽然API测试的格式看起来像webhttp调用,但是执行的测试类型类似于其他应用程序的测试类型。API是一个应用程序调用另一个应用程序服务的一种方式。API可以提供企业软件调用之外的功能。例如天气、运动成绩、股市行情和许多其他类型的数据,都可以通过商业API获取。API通常使用代表性的状态传输(REST)接口。这使HTTP调用能够访问通用资源标识符(通常称为URI),该标识符执行对服务的调用。要测试AP_api调试是什么意思?
文章浏览阅读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
文章浏览阅读2w次。苹果手机的录音功能在哪?很多小伙伴平常会需要录音,但是在苹果手机中找不到这样的功能,如果你觉得苹果手机并没有这样的功能,那可是大错特错。在苹果手机里面,我们可以借助苹果手机的自带应用——语音备忘录进行录音。操作方法:1.打开苹果手机,在桌面应用中找到语音备忘录2.在界面上点击红色的按钮开始录音3.完成录音之后点击红色的按钮停止4.新录制完成的音频会自动保存在语音备忘录以iOS 1..._苹果手机录音功能在哪
文章浏览阅读1.5k次。基于VR技术,搭建电力输电仿真系统用于培训,提供用户沉浸式学习体验、交互式操作体验,VR设备能够提供沉浸式真实感的模拟场景,使得输电线路巡检内容视觉化,跨越了空间和时间的限制,有针对性的解决传统输电运检室对新员工培训的所遇到的困难.并且借助VR设备交互性特点,给学员提供误操作带来的严重后果的虚拟体验,目前高压电力设备的操作培训是基于实物进行的,不仅有较高的危险性,还不能辨别操作者是否规范操作。在输..._vr 电力线路
文章浏览阅读1.6w次。Android平台上录制视频时,如果是横屏录制(手机逆时针旋转90度),则录制的视频时不带角度的。如果是竖屏录制(正常的拿手机的姿势),此时的录制的视频的旋转角度是90度。如果再旋转90度,此时一般音量键和关屏键朝下,此时的视频的旋转角度是180。以此类推。所以在手机上的视频一般会有4中角度的视频,播放时,要对视频资源进行旋转后在进行播放。一般而言,带角度的视频和不带角度的视频,数据帧里面的宽_displaymatrix: rotation of -90.00 degrees
文章浏览阅读1w次,点赞11次,收藏68次。本文首发于个人网站,永久地址:https://iiter.cn/blogs/13 点进去给几个访问量也行啊github 仓库源代码:github文章目录MQTT 的概念和其他传输协议的区别MQTT 客户端的语言支持搭建基于 nodejs 的 MQTT 服务器创建服务端创建客户端推送创建客户端接收测试功能MQTT 的概念MQTT(Message Queue Telemetry Transp..._mqttnet.server 支持js客户端吗?
文章浏览阅读3.8k次,点赞2次,收藏4次。在Java中有一个与if-else作用相似的东西,那就是switch-case。这就是Java中Switch-case语句的基本用法。要根据学生的成绩等级,判断学生的成绩范围。_java switch case用法举例
文章浏览阅读4k次。1 引言随着计算机应用的不断普及,学生动手组装计算机的热情也在不断高涨,兼容PC机以其价格低廉 (相对于品牌机)而深受在校大学生的喜爱,学生通过这门课程的学习,不仅能掌握计算机硬件的理论知识,更为自己能独立组装计算机(DIY)而对该课程产生了浓厚的兴趣。目前,很多高校开始把“计算机组装与维护”作为选修或开放实验课程来开设,其目的是为了培养学生的实践动手能力,掌握一技之长。由于现行的理论或实验教材,..._为什么要学计算机组装与维护
文章浏览阅读1.4w次,点赞15次,收藏73次。通过关卡流可以在需要的时候动态加载关卡,不需要的时候卸载,降低内存使用率,构建大型场景。通过简单的示例了解关卡流的用法。1、新建一个两个关卡,在关卡里分别放一个"Level1"和"Level2"的文本,保存文件名为StreamLevel1和StreamLevel22、新建一个空关卡,并打开Levels窗口3、在Levels界面,将StreamLevel1和StreamLevel..._关卡流
文章浏览阅读1.1k次。问题现象NC中间件启动时一直卡在这个界面不进行加载。问题分析1、查看了ncSysconfig,发现了客户的jvm参数有一段异常。客户在部署的时候少填写了一段jar包。造成中间件启动异常。上面是正确写法,下面是异常填写。修改后启动正常。2、后续客户加上友云音的jvm参数后,发现中间件启动异常缓慢,之前启动中间件5min左右,现在启动了10min还在继续。于是查看了客..._nc中间件一直打不开
文章浏览阅读194次。有3dmax效果图渲染需求可以使用渲染100(注册填邀请码‘7788’可领券免费测试)检查灯光材质细分,全局细分,灯光缓存细分是否过高,如果参数过高,尝试调低参数渲染。可以试一下优化场景的工具,清理空物体、空代理、适当塌陷精简场景、清理场景垃圾等。、在vray全局开关勾选最大射线强度。通过隐藏或删除模型的方式逐步排查。、检查是否存在坡度渐变材质。、清理空物体等场景垃圾。