首先需要明白 Redux 的单一状态树的概念,所谓的单一状态树,就是指“所有的 state 都以一个对象树的形式储存在一个单一的 store 中。

比如我们有这么一个状态树(或者你叫它状态对象也行):

{
text : 'Hello world'
}

这个状态树就只有一个节点 text,可以用来描述页面中某个文本的内容,比如说一个p标签:

<p> Hello world </p>

当我们把状态树改变之后,比如:

{
text : 'Hello Stark'
}

那么p标签也要改变:

<p> Hello Stark </p>

下面就是Redux最基础的概念:

“页面中的所有状态or数据,都应该用这种状态树的形式来描述;页面上的任何变化,都应该先去改变这个状态树,然后再通过某种方式实现到页面上。”

或者换句话说,我们要做的核心工作,就是用单个对象去描述页面的状态,然后通过改变这个对象来操控页面。

下面就可以解释 Redux 的几个核心概念了:

一、Action

Action 的任务是描述“发生了什么事情?”

比如刚才那个例子中我们把 text 从 “Hello world” 变成了 “Hello Stark” ,那么我们应该用一个 Action 对象来描述我们的行为:

function changeText(){
return {
type: 'CHANGE_TEXT',
newText: 'Hello Stark'
}
}

这个函数会返回一个 Action 对象,这个对象里描述了“页面发生了什么”。随后这个对象会被传入到 Reducer 中。

二、Reducer

Reducer 的任务是根据传入的 Action 对象去修改状态树。

或者简单地讲 Reducer 就是一个纯函数, 根据传入的 当前state 和 action ,返回一个新的 state :

(state, action) => newState

比如我们这个例子中的 Reducer 应该是这样的:

const initialState = {
text : 'Hello world'
} function Reducer(state=initialState, action) {
switch(action.type) {
case 'CHANGE_TEXT':
return {
text : 'Hello Stark'
}
default:
return state;
}
}

三、Store

Store 就是把 Reducer 和 action 联系到一起的对象。Store 有以下职责:

  • 维持应用的 state;
  • 提供 getState() 方法获取 state;
  • 提供 dispatch(action) 方法更新 state;
  • 通过 subscribe(listener) 注册监听器;

简单地说就是你可以这样产生一个 Store :

import { createStore } from 'redux'

//这里的 Reducer 就是刚才的 Reducer 函数
let store = createStore(Reducer);

然后你可以通过 dispatch 一个 action 来让它改变状态:

store.dispatch( changeText() );

store.getState(); // { text : 'Hello Stark' }

四、和 React 结合

事实上,Redux 提供的主要功能就只有上面这些了,实际上它确实非常简陋(源码不到2kb),稍微熟练的程序员可以很轻松地独立实现上面提到的东西。

这里需要再强调一下:Redux 和 React 之间没有关系。Redux 可以搭配 React、Angular 甚至纯 JS。但是 Redux 还是比较适合和 React 搭配的,因为 React 允许你以 state 的形式来描述界面,而 Redux 非常擅长控制 state 的变化。

Redux 和 React 的结合需要用到 redux-react 这个库,具体的实现可以参考:

  1. 搭配 React | Redux 中文文档
  2. 用React+Redux+ES6写一个最傻瓜的Hello World

相关学习地址:http://www.imooc.com/article/77290#

https://www.cnblogs.com/itlyh/p/6057518.html

http://cn.redux.js.org/docs/introduction/CoreConcepts.html

原文链接:https://www.zhihu.com/question/41312576/answer/90493435

最新文章

  1. configparser模块
  2. ubuntu启动器和dash里应用图标不正常
  3. 我给女朋友讲编程html系列(4) -- html常用简单标签
  4. 有关Transaction not successfully started问题解决的方法
  5. POJ3189_Steady Cow Assignment(二分图多重匹配/网络流+二分构图)
  6. 深入浅出Ajax(三)
  7. 【java】随机生成6位的数字
  8. Java开发笔记(六十)匿名内部类的优势
  9. reset()方法的使用、jq下面reset()的正确使用方法
  10. SSH上传/下载本地文件到linux服务器
  11. Vue.js绑定内联样式
  12. 【JQuery】jQuery(document).ready(function($) { });的几种表示方法及load和ready的区别
  13. JSP 插入到数据库的数据出现 “SQLServerException: 将截断字符串或二进制数据” 错误解决方案
  14. Django FBV/CBV、中间件、GIT使用
  15. 20155239 2016-2017-2 《Java程序设计》第7周学习总结
  16. 那个你经常用的abs函数(取绝对值)真的总是返回非负数吗?
  17. 0201-开始使用Spring Cloud实战微服务准备工作
  18. Ueditor百度编辑器插件的安装
  19. 【4Sum】cpp
  20. 【BZOJ3319】黑白树 并查集

热门文章

  1. Java 实现《编译原理》简单词法分析功能 - 程序解析
  2. windows时钟服务设置
  3. C#调用C++的dll各种传参
  4. SpringBoot 在IDEA中实现热部署(实用版)(引入)
  5. PHP---pdo和mongodb的操作使用
  6. Spark入Hbase的四种方式效率对比
  7. jquery text选择器 语法
  8. “不是一个有效的Win32应用程序”
  9. touch:创建文件及修改文件时间戳
  10. RedHat6.2系统安装ipvsadm+keepalived