react全局状态管理_react状态管理redux

Redux(上)

结合阮老师的技术博客,将自己吸收到的内容做了个整理:

曾经有人说过这样一句hua : 如果你不知道是否需要Redux,那就是不需要它。

从组建层面考虑,什么样子的需要redux;某个组件的状态需要共享,

某个状态需要在任何地方都可以拿到,

一个组件需要改变全局状态,

一个组件需要改变另一个组件的状态

一)Redux的设计思想 很重要

1)web应用是一个状态机,试图与状态是一一对应的

2)所有的状态,保存在一个对象里面(唯一数据源)

二)基本概念和 API

1、store

store就是保存数据的地方,你可以把它看成一个容器。整个应用只能有一个Store

Redux提供createStore这个函数,用来生成Store,import {createStore} from 'redux'

/创建一个reducer文件夹 并引入reducer

const store = createStore(reducer)

export default store

2、state

Store对象包含所有数据。如果想得到某个时点的数据,就要对 Store 生成快照。这种时点的数据集合,就叫做 State。

当前时刻的 State,可以通过store.getState()拿到。import { createStore } from 'redux';

const store = createStore(fn);

const state = store.getState();

Redux 规定, 一个 State 对应一个 View。只要 State 相同,View 就相同。你知道 State,就知道 View 是什么样,反之亦然。

3、Action

State 的变化,会导致 View 的变化。但是,用户接触不到 State,只能接触到 View。所以,State 的变化必须是 View 导致的。Action 就是 View 发出的通知,表示 State 应该要发生变化了。

Action 是一个对象。其中的type属性是必须的,表示 Action 的名称。其他属性可以自由设置,社区有一个规范可以参考。const action = {

type: 'ADD_TODO',

payload: 'Learn Redux'

};

上面代码中,Action 的名称是ADD_TODO,它携带的信息是字符串Learn Redux。

可以这样理解,Action 描述当前发生的事情。改变 State 的唯一办法,就是使用 Action。它会运送数据到 Store。

4、Action Creator

View 要发送多少种消息,就会有多少种 Action。如果都手写,会很麻烦。可以定义一个函数来生成 Action,这个函数就叫 Action Creator。const ADD_TODO = '添加 TODO';

function addTodo(text) {

return {

type: ADD_TODO,

text

}

}

const action = addTodo('Learn Redux');

上面代码中,addTodo函数就是一个 Action Creator。

5、store.dispatch()

store.dispatch()是 View 发出 Action 的唯一方法。import { createStore } from 'redux';

const store = createStore(fn);

store.dispatch({

type: 'ADD_TODO',

payload: 'Learn Redux'

});

上面代码中,store.dispatch接受一个 Action 对象作为参数,将它发送出去。

结合 Action Creator,这段代码可以改写如下。store.dispatch(addTodo('Learn Redux'));​

6、Reducer

Store 收到 Action 以后,必须给出一个新的 State,这样 View 才会发生变化。这种 State 的计算过程就叫做 Reducer。

Reducer 是一个函数,它接受 Action 和当前 State 作为参数,返回一个新的 State。const reducer = function (state, action) {

// ...

return new_state;

};

整个应用的初始状态,可以作为 State 的默认值。下面是一个实际的例子。const defaultState = 0;

const reducer = (state = defaultState, action) => {

switch (action.type) {

case 'ADD':

return state + action.payload;

default:

return state;

}

};

const state = reducer(1, {

type: 'ADD',

payload: 2

});

上面代码中,reducer函数收到名为ADD的 Action 以后,就返回一个新的 State,作为加法的计算结果。其他运算的逻辑(比如减法),也可以根据 Action 的不同来实现。

实际应用中,Reducer 函数不用像上面这样手动调用,store.dispatch方法会触发 Reducer 的自动执行。为此,Store 需要知道 Reducer 函数,做法就是在生成 Store 的时候,将 Reducer 传入createStore方法。import { createStore } from 'redux';

const store = createStore(reducer);

上面代码中,createStore接受 Reducer 作为参数,生成一个新的 Store。以后每当store.dispatch发送过来一个新的 Action,就会自动调用 Reducer,得到新的 State。

7、store.subscribe()

Store 允许使用store.subscribe方法设置监听函数,一旦 State 发生变化,就自动执行这个函数。import { createStore } from 'redux';

const store = createStore(reducer);

store.subscribe(listener);

显然,只要把 View 的更新函数(对于 React 项目,就是组件的render方法或setState方法)放入listen,就会实现 View 的自动渲染。

store.subscribe方法返回一个函数,调用这个函数就可以解除监听。let unsubscribe = store.subscribe(() =>

console.log(store.getState())

);

unsubscribe();​

三)举个例子

简单计数器的例子:麻雀虽小,五脏俱全

主要是观察store中的三个方法:

1、store.getState(); 在视图层通过该方法取到存储在store中的state。下图中23、24行代码

2、store.dispatch(); 在视图层通过该方法发送一个actions,去通知reducers去改变state值。下面的reducer函数

3、store.subscribe(); 通过该函数设置监听,一旦state发生改变,就会调用该函数,重新渲染视图层,如下面的31行代码

很明显 redux中 reducer和Action Creators都是一个纯函数,这就要求他们不允许:直接修改 state 参数对象

请求 API

调用不纯的函数,比如 Data.now() Math.random()

那这样的话,异步操作是如何实现的呢,这就需要借助中间件redux-thunk或者redux-sage在发出action到reducer接收到action之间来执行异步操作。(redux-thunk、redux-sage介绍参考简书)const Counter = ({ value, onIncrement, onDecrement }) => (

{value}

+

-

);

const reducer = (state = 0, action) => {

switch (action.type) {

case 'INCREMENT': return state + 1;

case 'DECREMENT': return state - 1;

default: return state;

}

};

const store = createStore(reducer);

const render = () => {

ReactDOM.render(

value={store.getState()}

onIncrement={() => store.dispatch({type: 'INCREMENT'})}

onDecrement={() => store.dispatch({type: 'DECREMENT'})}

/>,

document.getElementById('root')

);

};

render();

store.subscribe(render);

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

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

相关文章

edges2shoes数据集下载_edges2cats

edges2cats是一款十分有趣味的生成猫咪的游戏,在这款游戏是以多种不同的图形相结合,来生成你所想要生成的画面,游戏的玩法非常的有趣,感兴趣的可以试玩哦!edges2cats游戏怎么玩 玩法介绍首先清除画面,根据你…

单片机机器周期怎么计算公式_单片机定时器周期计算公式

定时器是单片机的重要功能模块之一,在检测、控制领域有广泛应用。定时器常用作定时时钟,以实现定时检测,定时响应、定时控制,并且可以产生ms宽的脉冲信号,驱动步进电机。定时和计数的最终功能都是通过计数实现&#xf…

mac 下mysql工具_mysql之工具的使用总结(mac版本)

13.mysql Mac终端操作12.MySql在Mac上的安装与配置详解;11.mac下安装mysql5.7.18,连接出现Access denied for user rootlocalhost (using password: YES)13.mysql Mac终端操作1.启动mysql :brew services start mysql2.登陆mysql : mysql -u…

sqoop同步时间戳到mysql_在sqoop导入中使用24小时时间戳

我想从使用自由格式查询的oracle导入数据,并且需要以24小时格式存储时间戳。在sqoop导入中使用24小时时间戳sqoop import --connect jdbc:oracle:thin:(server credntials) \--username ***** --password ***** \--query "select emp_uid, emp_name, salary, t…

mysql权限系统的工作原理_Mysql权限系统工作原理

MySQL权限系统保证所有的用户可以严格地做他们假定被允许做的事情。当你连接一个MySQL服务器时, 你的身份由你从那连接的主机和你指定的用户名来决定,系统根据你的身份和你想做什么来授予权限。MySQL在认定身份中考虑你的主机名和用户名字,是…

mysql日志文件的类型和作用_Mysql日志文件和日志类型介绍_MySQL

日志文件类型MySQL有几个不同的日志文件,可以帮助你找出mysqld内部发生的事情:日志文件记入文件中的信息类型错误日志记录启动、运行或停止mysqld时出现的问题。查询日志记录建立的客户端连接和执行的语句。更新日志记录更改数据的语句。不赞成使用该日志…

ruby mysql 驱动_windows下Rails安装MySql驱动的配置

1.安装ruby这我就不废话了,安装很简单,网上资料也很多。安装完后再环境变量path里加入D:ruby\bin(视你的安装路径了)安装完后在命令行输入ruby -v, 会显示版本号,表示安装成功,我的版本号是1.8.62.安装rails我建议去官…

cross join 一张表没有值关联不出来数据_你是否还在对left join、right join和join有困扰呢?...

说到SQL,很多人可能用了挺久,但依然有个问题一直困扰着,那就是 left join、 join、 right join和 inner join等等各种 join的区别。网上搜,最常见的就是一张图解图,如下:接下来就来实际自己动手实验&#x…

MySQL如何修改表的储存方式_修改mysql默认存储引擎的方法

修改mysql默认存储引擎的方法,供大家学习参考。先来了解一下mysql存储引擎:mysql服务器采用了模块化风格,各部分之间保持相对独立,尤其体现在存储架构上。存储引擎负责管理数据存储,以及mysql的索引管理。通过定义的AP…

前端判断是否安装桌面应用_前端开发人员的桌面应用神器 Electron

01为什么用 JavaScript 来开发桌面应用?曾经的 JavaScript 脆弱、简陋、甚至有被边缘化的危险,不过 JavaScript 在经过了两次飞跃后(以 V8 为首的 JavaScript 引擎和 Node.js 的问世),不再受人欺负,早已升级…

mysql 导出csv 多列_从包含300多列的csv,txt或xls文件创建MySQL表

你可以用一些langague C ,PHP解析txt文件......然后构建一个请求并执行它。PHP和PDO :: module将使这个最简单。我不知道某个程序是否已经完成这项工作。这是一个解决方案。如果您选择这样做并遇到麻烦,欢迎您。每个stackoverflow成员都会帮助您。编辑&a…

mysql error 1594_【MySQL】解决mysql的 1594 错误-阿里云开发者社区

对于主从架构的mysql,当发生主机断电或者其他原因异常crash的时候, slave的容易发生读取binlog出错的问题,最常见的是show slave status \G;Master_Log_File: mysql-bin.000029Read_Master_Log_Pos: 3154083Relay_Log_File: relay-bin.000478Relay_Log_Pos: 633Rel…

mysql innodb文件_MySQL的InnoDB文件介绍

MySQL一个显著的特点是其可插拔的存储引擎,因此MySQL文件分为两种,一种是和MySQL数据库本身相关 的文件,一种是和存储引擎相关的文件。本文主要介绍和InnoDB存储引擎相关的文件。表空间文件InnoDB在存储上也模仿了Oracle的设计,数…

python中与label类似的控件是_python中tkinter的使用(控件整理)(一)

1、使用tkinter.Tk() 生成主窗口(windowtkinter.Tk()):window.title(标题名)修改框体的名字,也可在创建时使用className参数来命名;window.resizable(0,0)框体大小可调性,分别表示x,y方向的可变性;1表示可变,0表示不可…

jdbc dao 工具类mysql_Java基于JDBC实现事务,银行转账及货物进出库功能示例

本文实例讲述了Java基于JDBC实现事务,银行转账及货物进出库功能。分享给大家供大家参考,具体如下:1. 转账业务转账必须执行2个sql语句(update更新)都成功的情况下,提交事务,如果有一个失败,则2个都回滚事务…

冒险岛单机版mysql_冒险岛单机版

这款《冒险岛单机版》经验是盛大冒险岛的100倍?最新盛大地图及BOSS,甚至包括盛大没有地图BOSS及现金装备,地图包括新加坡,马来西亚,台湾,可口可乐城,闹鬼宅邸,暹罗等等?。25驾坐骑&#xff0c…

python与html5搭建聊天室_html5 websocket 新版协议聊天室 服务端(python版)

网上找了很多代码都是旧版协议的,研究了很久终于弄清楚了 现在发个用新版协议写的服务端代码出来(这个代码是从网上旧版协议改过来的)最要就是握手协议和发送接受字符的方式变了# incodingutf-8import socketimport structimport hashlibimport threading,randomimp…

mysql数据库开发笔记_MySQL数据库生成数据库说明文档

在半年多前为一个MySQL数据库生成过数据库说明文档,今天要重新生成一份,但是发现完全不记得当时是怎么生成的,只能在网上搜索重来一遍,所以今天特意把这个过程记录一下。一、安装使用MySQL数据库表结构导出器DBExportDoc V1.0 For…

java 字符串缓冲区_详解Java中字符串缓冲区StringBuffer类的使用

StringBuffer 是一个线程安全的可变的字符序列。它继承于AbstractStringBuilder,实现了CharSequence接口。StringBuilder 也是继承于AbstractStringBuilder的子类;但是,StringBuilder和StringBuffer不同,前者是非线程安全的&#…

rabbitmq java文档_RabbitMQ文档翻译——Hello World!(上)

文章主要翻译自RabbitMQ官方文档,主要是为了练习英语翻译,顺便学习一下RabbitMQ😶其中也记录了一些爬过的坑IntroductionRabbitMQ is a message broker. The principal idea is pretty simple: it accepts and forwards messages. You can th…