react-redux一点就透,我这么笨都懂了!
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一点就透,我这么笨都懂了!相关推荐
- 实例讲解基于 React+Redux 的前端开发流程
前言:在当下的前端界,react 和 redux 发展得如火如荼,react 在 github 的 star 数达 42000 +,超过了 jquery 的 39000+,也即将超过前几年比较火的an ...
- React Redux: 从文档看源码 - Components篇
注:这篇文章只是讲解React Redux这一层,并不包含Redux部分.Redux有计划去学习,等以后学习了Redux源码以后再做分析 注:代码基于现在(2016.12.29)React Redux ...
- React Redux 进阶: Hooks 版本用法 Custom Context 局部 Store 实践
React Redux 进阶: Hooks 版本用法 & Custom Context 局部 Store 实践 文章目录 React Redux 进阶: Hooks 版本用法 & Cu ...
- React Redux 与胖虎
这是一篇详尽的 React Redux 扫盲文. 对 React Redux 已经比较熟悉的同学可以直接看 <React Redux 与胖虎他妈>. 是什么 React Redux 是 R ...
- React Redux 与胖虎他妈
本文将涉及以下三块内容: 多 Reducer 中间件 封装组件方便获取 Store 前言 在上一篇文章<React Redux与胖虎> 中我们详尽地介绍了 React Redux,也写了一 ...
- React + Redux
相当长一段时间以来,我一直在React和Redux中实现应用程序.在过去的几年里,我写了两本关于它的电子书,并发布了学习React及其生态系统的课程平台.课程平台甚至内置在React和Redux中.我 ...
- 使用React,Redux,redux-sage构建图片库(翻译)
看到这篇文章build an image gallery using redux saga,觉得写的不错,长短也适中. 文后有注释版的github代码库,请使用comment分枝. Flickr AP ...
- React+Redux开发实录(一)搭建工程脚手架
React+Redux开发实录(一)搭建工程脚手架 React+Redux开发实录(二)React技术栈一览 搭建工程脚手架 准备工作 安装node 安装git 安装一款前端IDE 推荐VSCode, ...
- 基于 react, redux 最佳实践构建的 2048
前段时间 React license 的问题闹的沸沸扬扬,搞得 React 社区人心惶惶,好在最终 React 团队听取了社区意见把 license 换成了 MIT.不管 React license ...
最新文章
- Biopython(py012)统计碱基数
- MAC 开机密码破解
- 盘点机器学习和统计模型的差异
- 在不是Thread类的子类中,如何获取线程对象的名称呢?
- SQLServer存储过程的返回值 查询分析器/程序
- php读取移动硬盘数据,移动硬盘打不开,数据怎么恢复?
- Git提示Please move or remove them before you switch branches.
- C# 解析 Targa文件 (TGA) 图形
- webdriver 的三种等待方式
- django-单表的增删改查-用户部门表
- 被坑的过来人告诉你,为什么数据中台永远都搞不成?
- datatable 操作列根据权限动态展现_不会Excel透视表?教你一招轻松做出动态报表...
- wps实现项目编号转成文本形式
- 2021最新学习路线,Java快速入门到精通(附Java教学视频)
- Mangos地区代码
- 深度残差网络+自适应参数化ReLU激活函数(调参记录2)
- Collaborative Evolutionary Reinforcement Learning
- 适合练习听力的英文电影推荐
- 怎样制作一个漂亮的艺术二维码?
- 网络安全通识全解|第10期 安全上网你要懂得的事