1. 目录

  • redux简介
  • 案例
  • react-redux核心介绍

2. redux简介

  • redux是react全家桶的一员,它试图为 React 应用提供「可预测化的状态管理」机制。

  • Redux是将整个应用状态存储到到一个地方,称为store

  • 里面保存一棵状态树(state tree)

  • 组件可以派发(dispatch)行为(action)给store,而不是直接通知其它组件

  • 其它组件可以通过订阅store中的状态(state)来刷新自己的视图

3. 安装

npm install --save redux
复制代码

4. redux核心

4.1 State

state是数据集合

可以理解为工厂加工商品所需的原材料

4.2 action

State的变化,会导致View的变化。但是,用户接触不到 State,只能接触到View 所以,State的变化必须是 View导致的。

action就是改变state的指令,有多少操作state的动作就会有多少action。

可以将action理解为描述发生了什么的指示器

4.3 reducer 加工函数

action发出命令后将state放入reucer加工函数中,返回新的state。 可以理解为加工的机器

4.4 store

store 可以理解为有多个加工机器的总工厂

let store = createStore(reducers);
复制代码

Store 就是把它们联系到一起的对象。Store 有以下职责:

维持应用的 state;
提供 getState() 方法获取 state;
提供 dispatch(action) 方法更新 state;
通过 subscribe(listener) 注册监听器;
通过 subscribe(listener) 返回的函数注销监听器。
复制代码

我们可以通过store.getState()来了解工厂中商品的状态, 使用store.dispatch发送action指令。

5. 经典案例

这是一个redux的经典案例

  • 定义reducer函数根据action的类型改变state
  • actions 定义指令
  • 通过createStore创建store
  • 调用store.dispatch()发出修改state的命令
import { createStore } from 'redux'const reducer = (state = {count: 0}, action) => {switch (action.type){case 'INCREASE': return {count: state.count + 1};case 'DECREASE': return {count: state.count - 1};default: return state;}
}const actions = {increase: () => ({type: 'INCREASE'}),decrease: () => ({type: 'DECREASE'})
}const store = createStore(reducer);store.subscribe(() =>console.log(store.getState())
);store.dispatch(actions.increase()) // {count: 1}
store.dispatch(actions.increase()) // {count: 2}
store.dispatch(actions.increase()) // {count: 3}复制代码

我们可以直接在react component上使用store.dispatch,但是这样不太方便,这个时候我们需要react-redux

class Todos extends Component {render(){return(<div onCLick={()=>store.dispatch(actions.delTodo()) }>test</div>)}
}
复制代码

6. react-redux

Redux 官方提供的 React 绑定库。 具有高效且灵活的特性。

6.1 安装

npm install --save react-redux
复制代码

6.2 核心

  • < Provider store>
  • connect([mapStateToProps], [mapDispatchToProps], [mergeProps], [options])

Provider 内的任何一个组件(比如这里的 Comp),如果需要使用 state 中的数据,就必须是「被 connect 过的」组件——使用 connect 方法对「你编写的组件(MyComp)」进行包装后的产物。

这个函数允许我们将 store 中的数据作为 props 绑定到组件上。

简单的流程如下图所示:

react-redux中的connect方法将store上的getState 和 dispatch 包装成组件的props。

将之前直接在组件上dispatch的代码修改为如下:

index.js

import React, { Component } from 'react';
import store from '../store';
import actions from '../store/actions/list';
import {connect} from 'react-redux';class Todos extends Component {render(){return(<div onCLick={()=>this.props.del_todo() }>test</div>)}
}export default connect(state=>state,actions
)(Todos);
复制代码

Provider 能拿到关键的store并传递给每个子组件

7. connect如何工作的?

connect() 接收四个参数,它们分别是 mapStateToProps , mapDispatchToProps, mergeProps 和 options 。

7.1 mapStateToProps这个函数允许我们将 store 中的数据作为 props 绑定到组件上。

reducer.js

export default function (state = { lists: [{text:'移动端计划'}],newType:'all'}, action) {switch (action.type) {case types.ADD_TODO:return {...state,lists:[...state.lists,{text:action.text}]}case types.TOGGLE_TODO:return {...state,lists:state.lists.map((item,index)=>{if(index == action.index){item.completed = !item.completed}return item})}case types.DEL_TODO:return {...state,lists:[...state.lists.slice(0,action.index),...state.lists.slice(action.index+1)]}case types.SWITCH_TYPE:console.log({...state,newType:action.newType})return {...state,newType:action.newType}default:return state;}
}
复制代码

在reducer.js中,定义了初始化的state,通过connect方法,我们就能使用this.props.lists拿到初始化的state。

import React, { Component } from 'react';
import store from '../store';
import actions from '../store/actions/list';
import {connect} from 'react-redux';class Todos extends Component {render(){return({+ <ul>+    this.props.state.lists.map(list =>(+        <li>{list.text}</li>+    ))+ </ul>   }<div onCLick={()=>this.props.del_todo() }>test</div>)}
}export default connect(state=>state,actions
)(Todos);
复制代码

当 state 变化,或者 ownProps 变化的时候,mapStateToProps 都会被调用,计算出一个新的 stateProps,(在与 ownProps merge 后)更新给 MyComp。

7.2 mapDispatchToProps(dispatch, ownProps): dispatchProps connect 的第二个参数是 mapDispatchToProps,它的功能是,将 action 作为 props 绑定到 MyComp 上。

action.js

import * as types from "../action-types";export default{add_todo(text){return { type: types.ADD_TODO, text: text}},del_todo(idx){return {type:types.DEL_TODO, index: idx}},toggle_todo(index){return {type:types.TOGGLE_TODO, index}},del_todo(index){return {type:types.DEL_TODO, index}},switch_type(newType){return {type:types.SWITCH_TYPE, newType}}
}
复制代码

我在action.js中定义的修改状态的命令,会通过connect 的 mapDispatchToProps方法变为props绑定在reac组件上。

我们可以方便得使用去调用

    <div onCLick={()=>this.props.del_todo() }>test</div>
复制代码

8. 深入

了解到这里,我们会发现并没有使用store.dispatch方法去发出命令,但是state已经修改,view也变化了,那么到底发生了什么?

store.dispatch(actions.increase())
复制代码

关键的是connect()

connect原理简化版

import React,{Component} from 'react';
import {bindActionCreators} from 'redux';
import propTypes from 'prop-types';export default function(mapStateToProps,mapDispatchToProps){return function(WrapedComponent){class ProxyComponent extends Component{static contextTypes = {store:propTypes.object}constructor(props,context){super(props,context);this.store = context.store;this.state = mapStateToProps(this.store.getState());}componentWillMount(){this.unsubscribe = this.store.subscribe(()=>{this.setState(mapStateToProps(this.store.getState()));});}componentWillUnmount(){this.unsubscribe();}render(){let actions= {};if(typeof mapDispatchToProps == 'function'){actions = mapDispatchToProps(this.store.disaptch);}else if(typeof mapDispatchToProps == 'object'){console.log('object', mapDispatchToProps)actions = bindActionCreators(mapDispatchToProps,this.store.dispatch);}return <WrapedComponent {...this.state} {...actions}/>}}return ProxyComponent;}
}
复制代码

1.state的返回 connect中对于Provided父组件上传来的store,通过将状态返回

mapStateToProps(this.store.getState());
复制代码

通过 Redux 的辅助函数 bindActionCreators(),用dispatch监听每一个action。

 bindActionCreators(mapDispatchToProps,this.store.dispatch);
复制代码

所以调用props上的方法时,会自动发起store.dispach(XXX)事件,发出命令

react-redux简单例子项目链接

参考文章

react-redux到这里分析结束,后面会继续写redux中间件的相关文章!

觉得好玩就关注一下~欢迎大家收藏写评论~~~

react-redux一点就透,我这么笨都懂了!相关推荐

  1. 实例讲解基于 React+Redux 的前端开发流程

    前言:在当下的前端界,react 和 redux 发展得如火如荼,react 在 github 的 star 数达 42000 +,超过了 jquery 的 39000+,也即将超过前几年比较火的an ...

  2. React Redux: 从文档看源码 - Components篇

    注:这篇文章只是讲解React Redux这一层,并不包含Redux部分.Redux有计划去学习,等以后学习了Redux源码以后再做分析 注:代码基于现在(2016.12.29)React Redux ...

  3. React Redux 进阶: Hooks 版本用法 Custom Context 局部 Store 实践

    React Redux 进阶: Hooks 版本用法 & Custom Context 局部 Store 实践 文章目录 React Redux 进阶: Hooks 版本用法 & Cu ...

  4. React Redux 与胖虎

    这是一篇详尽的 React Redux 扫盲文. 对 React Redux 已经比较熟悉的同学可以直接看 <React Redux 与胖虎他妈>. 是什么 React Redux 是 R ...

  5. React Redux 与胖虎他妈

    本文将涉及以下三块内容: 多 Reducer 中间件 封装组件方便获取 Store 前言 在上一篇文章<React Redux与胖虎> 中我们详尽地介绍了 React Redux,也写了一 ...

  6. React + Redux

    相当长一段时间以来,我一直在React和Redux中实现应用程序.在过去的几年里,我写了两本关于它的电子书,并发布了学习React及其生态系统的课程平台.课程平台甚至内置在React和Redux中.我 ...

  7. 使用React,Redux,redux-sage构建图片库(翻译)

    看到这篇文章build an image gallery using redux saga,觉得写的不错,长短也适中. 文后有注释版的github代码库,请使用comment分枝. Flickr AP ...

  8. React+Redux开发实录(一)搭建工程脚手架

    React+Redux开发实录(一)搭建工程脚手架 React+Redux开发实录(二)React技术栈一览 搭建工程脚手架 准备工作 安装node 安装git 安装一款前端IDE 推荐VSCode, ...

  9. 基于 react, redux 最佳实践构建的 2048

    前段时间 React license 的问题闹的沸沸扬扬,搞得 React 社区人心惶惶,好在最终 React 团队听取了社区意见把 license 换成了 MIT.不管 React license ...

最新文章

  1. Biopython(py012)统计碱基数
  2. MAC 开机密码破解
  3. 盘点机器学习和统计模型的差异
  4. 在不是Thread类的子类中,如何获取线程对象的名称呢?
  5. SQLServer存储过程的返回值 查询分析器/程序
  6. php读取移动硬盘数据,移动硬盘打不开,数据怎么恢复?
  7. Git提示Please move or remove them before you switch branches.
  8. C# 解析 Targa文件 (TGA) 图形
  9. webdriver 的三种等待方式
  10. django-单表的增删改查-用户部门表
  11. 被坑的过来人告诉你,为什么数据中台永远都搞不成?
  12. datatable 操作列根据权限动态展现_不会Excel透视表?教你一招轻松做出动态报表...
  13. wps实现项目编号转成文本形式
  14. 2021最新学习路线,Java快速入门到精通(附Java教学视频)
  15. Mangos地区代码
  16. 深度残差网络+自适应参数化ReLU激活函数(调参记录2)
  17. Collaborative Evolutionary Reinforcement Learning
  18. 适合练习听力的英文电影推荐
  19. 怎样制作一个漂亮的艺术二维码?
  20. 网络安全通识全解|第10期 安全上网你要懂得的事

热门文章

  1. oracle odbc配置
  2. Metasploit介绍
  3. 把view放在地图覆盖物上
  4. impala的详细介绍--图文描述
  5. JMETER badboy 录制脚本
  6. dbutils mysql_使用DBUtils控制mysql事务
  7. python flask web部署_webapp开发之使用apache部署python flask webapp
  8. 技巧 | 数据有缺失值情况下的一个处理方法
  9. Python基本操作(一) 安装软件及开发工具
  10. linux统计某个字符个数,Linux统计一个文件中特定字符个数的方法