Redux 关系图解
Redux
是一款状态管理库,并且提供了react-redux
库来与React
亲密配合, 但是总是傻傻分不清楚这2者提供的API
和相应的关系。这篇文章就来理一理。
Redux
Redux 三大核心
Redux
的核心由三部分组成:Store
, Action
, Reducer
。
Store
: 是个对象,贯穿你整个应用的数据都应该存储在这里。Action
: 是个对象,必须包含type
这个属性,reducer
将根据这个属性值来对store
进行相应的处理。除此之外的属性,就是进行这个操作需要的数据。Reducer
: 是个函数。接受两个参数:要修改的数据(state) 和action
对象。根据action.type
来决定采用的操作,对state
进行修改,最后返回新的state
。
===== Store =====
{
todos: [],
visibilityFilter: 'SHOW_ALL'
}
===== Action =====
{
type: 'ADD_TODO',
text: 'Build my first Redux app'
}
===== Reducer =====
const todos = (state = [], action) => {
switch (action.type) {
case 'ADD_TODO':
return [
...state,
{
id: action.id,
text: action.text,
completed: false
}
]
default:
return state
}
}
Redux核心之间的关系
在上一部分,我们提到了,我们触发action
→ reducer来处理
。这就是二者之间的关系。那么我们怎么触发action
呢?Store
这个对象提供了dispatch方法
→ 触发action
。dispatch
方法接受action
对象作为参数。因此,我们可以了解三者之间的关系:
`store` ➡️ `dispatch` ➡️ `action` ⬅️ `reducer`
Store
我们通过redux
提供的createStore
这个方法来创建一个Store
。它接受对store
进行处理的reducer
作为参数。
Store
有三个方法:
getState
:用来获取store
里面存储的数据。dispatch
:store
里的数据不能直接修改,只能通过触发action
来进行修改,这个方法就是用来触发action
。subscibe
:订阅store
改变时,要进行的操作。比如在react
中,当store
改变时,我们需要调用render
方法对视图进行更新。
const store = createStore(reducer);
store.getState(); // { todos: [], visibilityFilter: 'SHOW_ALL' }
store.dispatch({
type: 'ADD_TODO',
text: 'Build my first Redux app'
});
store.subscibe(() => {
console.log(store.getState());
});
Reducer
我们可以将对store
的操作,写在一个reducer
中,比如:
function todoApp(state = initialState, action) {
switch (action.type) {
case SET_VISIBILITY_FILTER:
return Object.assign({}, state, {
visibilityFilter: action.filter
})
case ADD_TODO:
case TOGGLE_TODO:
return Object.assign({}, state, {
todos: todos(state.todos, action)
})
default:
return state
}
}
可以看到这个reducer
对store
的visibilityFilter
和todos
的两部分数据进行了处理。随着应用的复杂,如果我们把对所有数据的处理,都写在一个reducer
中,那么它会变得很冗杂。如果我们将对每一部分的数据的处理,写在一个单独的reducer
中,它接受该部分的数据作为state
。那么整个reducer
会变得整洁和清晰。
因此,redux
为我们提供了combineReducer
这个API
,帮助我们分开书写reducer
, 并且最终把这些reducer
给集合到一个根reducer
中。
// 对todos进行处理
function todos(state = [], action) {
switch (action.type) {
case ADD_TODO:
return [
...state,
{
text: action.text,
completed: false
}
]
default:
return state
}
}
// 对 visibilityFilter 进行处理
function visibilityFilter(state = SHOW_ALL, action) {
switch (action.type) {
case SET_VISIBILITY_FILTER:
return action.filter
default:
return state
}
}
// 生成 root reducer
function todoApp(state = {}, action) {
return {
visibilityFilter: visibilityFilter(state.visibilityFilter, action),
todos: todos(state.todos, action)
}
}
// 创建store
const store = createStore(todoApp)
react-redux
上一部分我们介绍了redux
的核心。可以看到,redux
是独立的应用状态管理工具。它是可以独立于react
之外的。如果我们需要在react
当中运用它,那么我们需要手动订阅store
的状态变化,来对我们的react
组件进行更新。那么react-reudx
这个工具,就帮我们实现了这个功能,我们只需对store
进行处理,react
组件就会有相应的变化。
这个工具主要提供两个API
:
connect
现在我们有了store
,那么我们怎么才能在我们的组件中对它们进行操作呢?connect
就为提供了这个功能。它接受mapStateToProps
, mapDispatchToProps
等作为参数。比如在我的TodoList
这个组件中需要用到todos
这部分数据,那么我完善mapStateToProps
这个函数,它接受store
中的state
作为参数,返回一个对象,属性就是state
中我们需要的数据:
const mapStateToProps = state => {
return {
todos: state.todos
}
}
mapStateToProps
就将我们的state
转换为了props
对象。
同样的,我们可能需要在组件中对state
进行处理。mapDispatchToProps
就是帮助我们在组件中通过props
调用dispatch
来触发action
的:
const mapDispatchToProps = dispatch => {
return {
onTodoClick: id => {
dispatch(toggleTodo(id))
}
}
}
最后我们调用connect
这个方法,将mapStateToProps
, mapDispatchToProps
生成的props
注入到需要使用它的组`中:
const VisibleTodoList = connect(
mapStateToProps,
mapDispatchToProps
)(TodoList)
这样,我们在TodoList
这个组件中,就能直接通过props.todos
获取到todos
中的数据, 通过props.onTodoClick
对todos
进行处理。
provider
上面我们调用connect
时,在mapStateToProps
和 mapDispatchToProps
我们分别用到了store
的state
和dispatch
。但是在组件中的store
是哪里凭空冒出来的呢?
provider
就是来解决这个事的。Provider
使它的子孙在调用connect
方法时,都能获取到store
。
const VisibleTodoList = connect(
mapStateToProps,
mapDispatchToProps
)(TodoList)
const App = () => (
<div>
<AddTodo />
<VisibleTodoList />
<Footer />
</div>
)
<Provider store={store}>
<App />
</Provider>
这样,Provider
的子孙组件都能在调用connect
时获取到store
。
总结
Redux:
store
,action
,reducer
store
:getState
,dispatch
,subscribe
combineReducers
createStore
store
➡️dispatch
➡️action
⬅️reducer
react-redux:
connect
: 将store
作为props
注入Provider
: 使store
在子孙组件的connect
中能够获取到。
来源:https://segmentfault.com/a/1190000011473973
Redux 关系图解的更多相关文章
- CGI、FastCGI和PHP-FPM关系图解
CGI.FastCGI和PHP-FPM关系图解 webapp即是php解析器等 当Web Server收到 index.php 这个请求后,会启动对应的 CGI 程序,这里就是PHP的解析器.接下 ...
- 简单实用UML关系图解
一句话UML,再记不住就要DPP了: 关系 图解 代码 备注 1:继承关系(Generalization) 2:实现关系(Realization) 3:依赖关系(Dependency) ...
- [转帖]UML类图关系图解
UML类图关系图解 https://www.cnblogs.com/TvvT-kevin/p/9357339.html 一.类结构 在类的UML图中,使用长方形描述一个类的主要构成,长方形垂直地分为三 ...
- 前端(十一):props、state及redux关系梳理
所谓状态机,是一种抽象的数据模型,是“事物发展的趋势”,其原理是事件驱动.广泛地讲,世界万物都是状态机. 一.状态机是一种抽象的数据模型 在react中,props和state都可以用来传递数据.这里 ...
- UML中关系图解
转自http://blog.csdn.net/duran1986/article/details/5573415 最近在教软件工程项目实践,就又仔细了解了下UML中各种关系的意义,虽然有点简单,但是有 ...
- UML类图中类与类的四种关系图解
国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html内部邀请码:C8E245J (不写邀请码,没有现金送)国内私 ...
- UML类图关系图解
一.类结构 在类的UML图中,使用长方形描述一个类的主要构成,长方形垂直地分为三层,以此放置类的名称.属性和方法. 其中, 一般类的类名用正常字体粗体表示,如上图:抽象类名用斜体字粗体,如User:接 ...
- mount过程分析之六——挂载关系(图解)【转】
转自:https://blog.csdn.net/zr_lang/article/details/40343899 引言 写到这里我们已经从mount文件系统调用的入口开始,分析到内核的mount,通 ...
- MVC与MVVM关系图解
随机推荐
- js判断条件为“假”的情况
以下6种情况判断结果为"假": 1.false(布尔类型) 2.null(用于定义空的或者不存在的引用) 3.undefined(未定义) 4.0(数值0) 5.''(空字符串) ...
- linux 系统下 zip 的加密压缩与解压缩命令
1.加密压缩 [small@sun shine]# zip -rP king java.zip java adding: java/ (stored 0%) adding: java/default/ ...
- #333 Div2 Problem B Approximating a Constant Range (尺取 && RMQ || 尺取 && multiset)
题目链接:http://codeforces.com/contest/602/problem/B 题意 :给出一个含有 n 个数的区间,要求找出一个最大的连续子区间使得这个子区间的最大值和最小值的差值 ...
- TTTTTTTTTTTTTT CDOJ Sliding Window 线段树(nlogn)或双端队列(n) 模板
题目链接: L - Sliding Window Time Limit:6000MS Memory Limit:131072KB 64bit IO Format:%lld & ...
- k8s的node节点,执行kubectl get XXX报错
报错现象: [root@localhost ~]# kubectl get nodes The connection to the server localhost:8080 was refused ...
- 微信浏览器video播放视频踩坑
video属性介绍 iOS的属性 playsinline On iPhone, video playsinline elements will now be allowed to play inlin ...
- 微信小程序访问后台出现 对应的服务器证书无效。控制台输入 showRequestInfo() 可以获取更详细信息。
检查微信开发者平台配置 https 服务端 nginx 配置 ssl 协议是否有效 在开发者工具中可以使用(详情 > 不校验合法域名.web-view(业务域名).TLS 版本以及 HTTPS ...
- ArrayList,Vector ,LinkedList的存储性能和特性
ArrayList,Vector,LinkedList : 两者都采用数组元素方式存储数据,此数组元素数大于实际存储的数据(以便于增加和插入元素),允许直接按照序号索引元素,但是插入元素涉及数组元素移 ...
- 【Python】学习笔记七:函数
函数的目的:重复使用相同的一段程序 函数的定义 下面是我自定义的一个求a,b,c三个参数平方和的函数 #a,b,c三个参数的平方和 def pow_sum(a,b,c): x = pow(a,2)+p ...
- 第一次试验报告&学习总结
打印输出所有的"水仙花数",所谓"水仙花数"是指一个3位数,其中各位数字立方和等于该数本身.例如,153是一个"水仙花数". 试验代码: p ...