当前位置: 首页 > news >正文

Redux学习与使用

Redux并不是必需的,只有在项目存在多交互、多数据源的场景才应该考虑使用,其设计思想可总结为:Web 应用是一个状态机,视图与状态是一一对应的,所有的状态,保存在一个对象里面。

一、基本概念及常用API

1、Store即是保存数据的地方,通过createStore函数生成Store

import { createStore } from 'redux';
const store = createStore(fn);

2、State就是状态,是数据的集合,可以通过store.getState()拿到

const state = store.getState();

3、Action 是一个对象,是View发出的通知,通知State该发生变化了,其中type属性是必须的

const action = {
  type: 'ADD_TODO',
  payload: 'Learn Redux'
};

4、Action Creator就是可以生成Action的函数

const ADD_TODO = '添加 TODO';

function addTodo(text) {
  return {
    type: ADD_TODO,
    text
  }
}

const action = addTodo('Learn Redux');

5、store.dispatch()是 View 发出 Action 的唯一方法

store.dispatch(addTodo('Learn Redux'));

6、Reducer 是一个纯函数,它接受 Action 和当前 State 作为参数,返回一个新的 State

const reducer = function (state, action) {
  // ...
  return new_state;
};

7、store.subscribe方法可设置监听函数,一旦 State 发生变化,就自动执行这个函数,调用该方法返回的函数,即可解除监听

import { createStore } from 'redux';
const store = createStore(reducer);

store.subscribe(listener);

let unsubscribe = store.subscribe(() =>
  console.log(store.getState())
);

unsubscribe();

二、Store的实现

生成Store的createStore方法可以接受两个参数

let store = createStore(reducer, window.STATE_FROM_SERVER)

Store 提供了三个方法: subscribe, dispatch, getState,其简单实现如下

const createStore = (reducer) => {
  let state; // 状态
  let listeners = []; // 监听

  const getState = () => state;

  const dispatch = (action) => {
    state = reducer(state, action);
    listeners.forEach(listener => listener());
  };

  const subscribe = (listener) => {
    listeners.push(listener);
    return () => {
      listeners = listeners.filter(l => l !== listener);
    }
  };

  dispatch({});

  return { getState, dispatch, subscribe };
};

三、Reducer的拆分和组合

可以将一个庞大的Reducer根据不同的属性处理,拆分不同的子函数,最终通过combineReducers方法合并

import { combineReducers } from 'redux';

const chatReducer = combineReducers({
  chatLog,
  statusMessage,
  userName
})

可以把所有子 Reducer 放在一个文件里面,然后统一引入

import { combineReducers } from 'redux'
import * as reducers from './reducers'

const reducer = combineReducers(reducers)

四、Redux工作流程

首先,用户发出 Action

store.dispatch(action);

然后,Store 自动调用 Reducer,并且传入两个参数:当前 State 和收到的 Action,Reducer 会返回新的 State

let nextState = todoApp(previousState, action);

State 一旦有变化,Store 就会调用监听函数。

// 设置监听函数
store.subscribe(listener);

listener可以通过store.getState()得到当前状态。如果使用的是 React,这时可以触发重新渲染 View。

function listerner() {
  let newState = store.getState();
  component.setState(newState);   
}

五、Redux中间件以及异步操作

异步操作就是在 Action 发出以后,过一段时间再执行 Reducer,这需求用到中间件。中间件就是一个函数,可以添加功能,通过applyMiddleware方法进行使用

import { applyMiddleware, createStore } from 'redux';
import createLogger from 'redux-logger';
const logger = createLogger();

const store = createStore(
  reducer,
  applyMiddleware(logger)
);

applyMiddlewares是 Redux 的原生方法,作用是将所有中间件组成一个数组,依次执行。

异步操作的思路可以理解为:

  • 操作开始时,送出一个 Action,触发 State 更新为"正在操作"状态,View 重新渲染
  • 操作结束后,再送出一个 Action,触发 State 更新为"操作结束"状态,View 再一次重新渲染

六、React-Redux的使用

React-Redux 将所有组件分成两大类:UI 组件(presentational component)和容器组件(container component)。

UI 组件有以下几个特征:

  • 只负责 UI 的呈现,不带有任何业务逻辑
  • 没有状态(即不使用this.state这个变量)
  • 所有数据都由参数(this.props)提供
  • 不使用任何 Redux 的 API
const Title =
  value => <h1>{value}</h1>;

容器组件的特征:

  • 负责管理数据和业务逻辑,不负责 UI 的呈现
  • 带有内部状态
  • 使用 Redux 的 API

React-Redux 提供connect方法,用于从 UI 组件生成容器组件

import { connect } from 'react-redux'

const VisibleTodoList = connect(
  mapStateToProps,
  mapDispatchToProps
)(TodoList)

TodoList是 UI 组件,VisibleTodoList就是由 React-Redux 通过connect方法自动生成的容器组件,mapStateToProps负责输入逻辑,即将state映射到 UI 组件的参数(props),mapDispatchToProps负责输出逻辑,即将用户对 UI 组件的操作映射成 Action

connect方法生成容器组件以后,需要让容器组件拿到state对象,才能生成 UI 组件的参数,React-Redux 提供Provider组件,可以让容器组件拿到state

import { Provider } from 'react-redux'
import { createStore } from 'redux'
import todoApp from './reducers'
import App from './components/App'

let store = createStore(todoApp);

render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
)

上面代码中,Provider在根组件外面包了一层,这样一来,App的所有子组件就默认都可以拿到state

Refs:

Redux 入门教程(一):基本用法

Redux 入门教程(二):中间件与异步操作

Redux 入门教程(三):React-Redux 的用法

相关文章:

  • 计算机组成原理知识总结(九)并行组织与结构
  • 带内全双工水声通信系统自干扰抵消技术研究框架与思路
  • 关于在使用elementui的tabs组件进行切换组件时会闪屏的解决方案
  • 网站被劫持了怎么办?
  • 二、字符串 String
  • Python数据类型转换
  • Protobuf 和JSON 性能分析
  • DCA培训心得笔记(二)
  • TB-RK1808M0最新固件烧录和驱动更新
  • (附源码)ssm高校社团管理系统 毕业设计 234162
  • C语言被创造出来的基础是什么?它的主要结构是什么?
  • error: Unexpected console statement (no-console) 解决办法
  • 神经系统分类和组成图表,神经系统的组成概念图
  • [Swift学习] 访问控制 Access Control, private、public、filePrivate等修饰符
  • [SQL]数据库语言学习
  • [LeetCode] Wiggle Sort
  • 【知识碎片】第三方登录弹窗效果
  • CAP 一致性协议及应用解析
  • js写一个简单的选项卡
  • Median of Two Sorted Arrays
  • Python 反序列化安全问题(二)
  • VirtualBox 安装过程中出现 Running VMs found 错误的解决过程
  • Yeoman_Bower_Grunt
  • 从零开始的无人驾驶 1
  • 记一次删除Git记录中的大文件的过程
  • 普通函数和构造函数的区别
  • 前端技术周刊 2018-12-10:前端自动化测试
  • LevelDB 入门 —— 全面了解 LevelDB 的功能特性
  • 关于Kubernetes Dashboard漏洞CVE-2018-18264的修复公告
  • 如何在 Intellij IDEA 更高效地将应用部署到容器服务 Kubernetes ...
  • ​ 轻量应用服务器:亚马逊云科技打造全球领先的云计算解决方案
  • #{}和${}的区别是什么 -- java面试
  • #HarmonyOS:软件安装window和mac预览Hello World
  • (4) openssl rsa/pkey(查看私钥、从私钥中提取公钥、查看公钥)
  • (android 地图实战开发)3 在地图上显示当前位置和自定义银行位置
  • (done) 两个矩阵 “相似” 是什么意思?
  • (java版)排序算法----【冒泡,选择,插入,希尔,快速排序,归并排序,基数排序】超详细~~
  • (Java岗)秋招打卡!一本学历拿下美团、阿里、快手、米哈游offer
  • (安全基本功)磁盘MBR,分区表,活动分区,引导扇区。。。详解与区别
  • (分享)一个图片添加水印的小demo的页面,可自定义样式
  • (附源码)ssm捐赠救助系统 毕业设计 060945
  • (力扣记录)235. 二叉搜索树的最近公共祖先
  • (入门自用)--C++--抽象类--多态原理--虚表--1020
  • (十)c52学习之旅-定时器实验
  • (数位dp) 算法竞赛入门到进阶 书本题集
  • (四)Controller接口控制器详解(三)
  • (淘宝无限适配)手机端rem布局详解(转载非原创)
  • (心得)获取一个数二进制序列中所有的偶数位和奇数位, 分别输出二进制序列。
  • (轉)JSON.stringify 语法实例讲解
  • ***利用Ms05002溢出找“肉鸡
  • ./include/caffe/util/cudnn.hpp: In function ‘const char* cudnnGetErrorString(cudnnStatus_t)’: ./incl
  • .mysql secret在哪_MySQL如何使用索引
  • .NET MVC第三章、三种传值方式
  • .NET 使用配置文件
  • .NET 事件模型教程(二)