React技术栈——Redux
Redux
1.Redux是什么?
Redux对于JavaScript应用而言是一个可预测状态的容器。换言之,它是一个应用数据流框架,而不是传统的像underscore.js或者AngularJs那样的库或者框架。
Redux最主要是用作应用状态的管理。简言之,Redux用一个单独的常量状态树(对象)保存这一整个应用的状态,这个对象不能直接被改变。当一些数据变化了,一个新的对象就会被创建(使用actions和reducers)。
2.核心概念
- actions
actions就是事件。actions传递数据给store,store获取来自actions的信息。actions内部就只是简单的具有一个type属性(通常是变量)的js对象,这个对象描述了actions的类型以及传递给store的信息。 - reducers
reducers是一些纯函数,它通过获取当前的state和一个action作为参数,再返回下一个state。简单来说,就是根据不同的action来完成state的变化。 - store
store对象保存应用的状态并提供一些帮助方法来存取状态,派发状态以及监听状态。全部的state由一个store表示,所有的action通过reducer返回一个新的状态对象。这使得Redux变得非常简单以及可预测。
3.Redux的基本使用
(1) 创建store
Redux的核心是store,Redux只是提供了规则和API,store的创建需要我们来完成,只有创建完store,才能够使用。
创建store,就要使用createStore方法。使用createStore方法时,需要涉及以下几个内容:
- state
- action
- reducer
以做一个计数器为例。
首先,要先定义一个初始的state,如下:
const initState = {
count:520
}
复制代码
然后,定义两个action对象,如下:
<!--定义增加的action-->
const increment = {
type:"INCREMENT"
}
<!--定义减少的action-->
const decrement = {
type:"DECREMENT"
}
复制代码
最后,编写reducer函数,如下:
<!--定义一个reducer,根据不同action中的type属性,去完成对state的状态更新-->
function reducer (state=initState,action){
switch (action.type){
case "ICREMENT":
return {count:state.count+1};
case "DECREMENT":
return {count:state.count-1};
default:
return state;
}
}
复制代码
当我们定义完reducer之后,就可以使用createStore方法创建store对象了,如下:
<!--创建store对象-->
const store = Redux.createStore(reducer)
复制代码
(2) 使用store
创建完store对象后,我们该怎么使用store呢?
store有如下几个API:
- getState:用于获取状态
- dispatch:用于派发状态
- subscribe:用于监听状态,一旦状态发生变化们,就会执行回调函数
使用如下:
<!--创建store对象-->
const store = Redux.createStore(reducer)
console.log(store.getState())
复制代码
<!--监听状态的变化-->
store.subscribe(()=>{
console.log("现在的状态是",store.getState())
})
复制代码
<!--通过dispatch来触发action对状态state的修改 -->
store.dispatch(increment)
store.dispatch(decrement)
复制代码
其实,action对象中还可以有其他的属性,从而实现对state值的修改,可以使用action creators函数来生成action,在函数内定义一个参数,就可以根据需求来修改state的值了,如下:
<!--用action creators函数创建增加的action-->
function increment(step) {
return{
type:"INCREMENT",
step
}
}
复制代码
<!--用action creators函数创建减少的action-->
function decrement(step) {
return{
type:"DECREMENT",
step
}
}
复制代码
接着要修改reducer,如下:
<!--定义一个reducer,根据不同action中的type属性,去完成对state的状态更新-->
function reducer (state=initState,action){
switch (action.type){
case "ICREMENT":
return {count:state.count+action.step};
case "DECREMENT":
return {count:state.count-action.step};
default:
return state;
}
}
复制代码
最后要在dispatch方法上调用,可以通过改变实参来实现想要的需求,如下:
store.dispatch(increment(1));
store.dispatch(increment(2));
store.dispatch(increment(3));
复制代码
(3) store的应用
由于Reducer是纯函数,所以Reducer函数中不能改变state,必须返回一个全新的对象,但是像在todosMVC案例中需要添加todo的方法要怎么来实现呢?
在Reducer函数中,不能改变state,因此todos这个数组就不能使用数组的方法了,应该使用对象的合并操作(Object.assign()).下面就使用Redux来实现todosMVC案例中的几个功能:
第一步,规划state,如下:
<!--初始化state-->
const initState = {
todos:[
{content:"html",complete:false},
{content:"css",complete:false},
{content:"js",complete:false},
],
visibility:"all"
}
复制代码
第二步,定义action,使用action creators来创建,如下:
<!--定义action creators-->
<!--添加todo-->
function addTodo(content){
return{
type:"ADD_TODO",
content
}
}
<!--设置todo的可见性-->
function setVisibility(filter){
return{
type:"SET_VISIBLLITY",
filter
}
}
复制代码
第三步,定义reducer,如下:
<!--定义reducer-->
function reducer(state=initState,action){
switch(action.type){
case "ADD_TODO":
var todos = [...state.todos,{content:action.content,done:false}]
return Object.assign({},state,{todos})
case "SET_VISIBILITY":
return Object.assign({},state,{visibility:action.filter})
default:
return state;
}
}
复制代码
第四步,创建store对象,如下:
<!--创建store对象-->
const store = Redux.createStore(reducer);
复制代码
第五步,使用store,如下:
<!--使用store-->
console.log(store.getState())
复制代码
(4)reducer的拆分与合并
如果是在真实的项目中,就会有很多的状态要管理,因此就可以分开定义reducer来处理各自的状态。reducer的拆分如下:
<!--定义todos状态的reducer-->
function todos(state=[],action){
switch (action.type){
case "ADD_TODO":
return [...state,{content:action.content,complete:false}];
default:
return state;
}
}
复制代码
<!--定义visibility对应的reducer-->
function visibility(state="all",action){
switch (action.type){
case "SET_VISIBILITY":
return action.filter;
default:
return state;
}
}
复制代码
然后合并两个reducer,如下:
function reducer (state=initState,action){
return{
todos:todos(state.todos.action),
visibility:visibility(state.visibility.action)
}
}
复制代码
还可以使用Redux提供的combineReducers方法,如下:
const reducer = Redux.combineReducers({
todos,
visibility
})
复制代码
总结
Redux是一个JavaScript库,用于管理应用的前端状态。Redux并非React应用的必须条件,但是随着网络应用的复杂性越来越高,状态管理不当可能会导致bug。Redux应用中的全局状态存储在单一数据源store中。因为状态的更新受到严格控制,使得Redux非常具有可预测性。实际上,开发人员喜欢Redux的主要原因之一就是它的可预测性。
转载于:https://juejin.im/post/5b77ce166fb9a019f1800001
React技术栈——Redux的更多相关文章
- 重谈react优势——react技术栈回顾
react刚刚推出的时候,讲react优势搜索结果是几十页. 现在,react已经慢慢退火,该用用react技术栈的已经使用上,填过多少坑,加过多少班,血泪控诉也不下千文. 今天,再谈一遍react优 ...
- react技术栈实践(2)
本文来自网易云社区 作者:汪洋 这时候还没完,又有两个问题引出来了. 按照上面的配置,第三方库 antd 竟然也被编译了,导致样式失败. react中,一旦包裹了子组件,子组件没办法直接使用 styl ...
- react技术栈实践(1)
本文来自网易云社区 作者:汪洋 背景 最近开发一个全新AB测试平台,思考了下正好可以使用react技术开发. 实践前技术准备 首先遇到一个概念,redux.这货还真不好理解,大体的理解:Store包含 ...
- React技术栈梳理
一.react是什么? react是一个js框架,可以用它来编写html页面,使用react后我们可以完全抛弃html(只需要一个主index文件),而用纯js来编写页面: 二.为什么要使用react ...
- 深入React技术栈之初入React世界
1.1 react简介 react并不是完整的MVM/MVVM框架,专注于提供清晰.简洁的View层解决方案. 传统开发模式,要更新页面需要手动操作DOM元素.如图1.1所示,React在DOM上封装 ...
- H5页面开发笔记(react技术栈)
1.子组件接收父组件的参数,要在子组件的componentDidMount函数中更改当前组件的state,若写在componentWillMount函数中,则会导致初始化界面UI的时候不能得到预期的效 ...
- 深入react技术栈解读
1. react实现virtual DOM ,如果要改变页面的内容,还是需要执行DOM操作,比原生操作DOM多了virtualDOM的操作(计算,对比等), 应该是更耗性能??? 2. react特点 ...
- 深入React技术栈之setState详解
抛出问题 class Example extends Component { contructor () { super() this.state = { value: 0, index: 0 } } ...
- 一个基于React整套技术栈+Node.js的前端页面制作工具
pagemaker是一个前端页面制作工具,方便产品,运营和视觉的同学迅速开发简单的前端页面,从而可以解放前端同学的工作量.此项目创意来自网易乐得内部项目nfop中的pagemaker项目.原来项目的前 ...
随机推荐
- 九九乘法表 C语言
无需输入,直接输出九九乘法表,特别简单. 运行结果如下: #include<stdio.h> int main() { ; ; , j = ; ; i < ; i++,b++) { ...
- 【C++】VS2017 不能将const char * 分配给 char *
我的方式是把结构体中定义的 char * 换成string #include <iostream> #include<string> using namespace std; ...
- php静态变量的运用
<?php $count = 5; function get_count() { static $count = 0; return $count++; } echo $count; echo ...
- 家庭记账本app进度之复选框以及相应滚动条的应用
这次主要是对于android中复选框的相应的操作.以及其中可能应用到的滚动条的相关应用.每一个复选框按钮都要有一个checkBox与之相对应. 推荐使用XML配置,基本语法如下:<CheckBo ...
- uni-app的初识(01)
1.什么是uni-app uni-app 是一个使用 Vue.js 开发所有前端应用的框架, 开发者编写一套代码, 可发布到IOS, Android, H5, 以及各种小程序(微信,百度)等多个平台. ...
- .net跨域接口服务器端配置
在项目Config文件中添加一下节点配置 <system.webServer> <httpProtocol> <customHeaders> <add nam ...
- Python 的while循环和for循环的使用
#循环 遍历 迭代 # while循环 a = 0while a <5: a =a+1 if a == 3: continueprint('我循环了')+str(a) # print ('我循环 ...
- django->model模型操作(数据库操作)
一.字段类型 二.字段选项说明 三.内嵌类参数说明abstract = Truedb_table = 'table_name' #表名,默认的表名是app_name+类名ordering = ['id ...
- 28.4 Calendar 日历
/* * Calendar:日历,提供了一些操作年月日时的方法 * 获取 * 修改 * 添加 */ public class CalendarDemo { public static void mai ...
- 听说你想要部署 Octopress?满足你
Octopress 是一个面向开发者的博客系统,广受程序员的喜爱.既然大家有需求,那么 Octopress 也要安排上~ 云开发(CloudBase)是一款云端一体化的产品方案 ,采用 serverl ...