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核心之间的关系

在上一部分,我们提到了,我们触发actionreducer来处理。这就是二者之间的关系。那么我们怎么触发action呢?Store这个对象提供了dispatch方法触发actiondispatch方法接受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
}
}

可以看到这个reducerstorevisibilityFiltertodos的两部分数据进行了处理。随着应用的复杂,如果我们把对所有数据的处理,都写在一个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这个方法,将mapStateToPropsmapDispatchToProps生成的props注入到需要使用它的组`中:


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

这样,我们在TodoList这个组件中,就能直接通过props.todos获取到todos中的数据, 通过props.onTodoClicktodos进行处理。

provider

上面我们调用connect时,在mapStateToPropsmapDispatchToProps我们分别用到了storestatedispatch。但是在组件中的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 关系图解的更多相关文章

  1. CGI、FastCGI和PHP-FPM关系图解

    CGI.FastCGI和PHP-FPM关系图解   webapp即是php解析器等 当Web Server收到 index.php 这个请求后,会启动对应的 CGI 程序,这里就是PHP的解析器.接下 ...

  2. 简单实用UML关系图解

    一句话UML,再记不住就要DPP了: 关系 图解 代码 备注 1:继承关系(Generalization)     2:实现关系(Realization)     3:依赖关系(Dependency) ...

  3. [转帖]UML类图关系图解

    UML类图关系图解 https://www.cnblogs.com/TvvT-kevin/p/9357339.html 一.类结构 在类的UML图中,使用长方形描述一个类的主要构成,长方形垂直地分为三 ...

  4. 前端(十一):props、state及redux关系梳理

    所谓状态机,是一种抽象的数据模型,是“事物发展的趋势”,其原理是事件驱动.广泛地讲,世界万物都是状态机. 一.状态机是一种抽象的数据模型 在react中,props和state都可以用来传递数据.这里 ...

  5. UML中关系图解

    转自http://blog.csdn.net/duran1986/article/details/5573415 最近在教软件工程项目实践,就又仔细了解了下UML中各种关系的意义,虽然有点简单,但是有 ...

  6. UML类图中类与类的四种关系图解

    国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html内部邀请码:C8E245J (不写邀请码,没有现金送)国内私 ...

  7. UML类图关系图解

    一.类结构 在类的UML图中,使用长方形描述一个类的主要构成,长方形垂直地分为三层,以此放置类的名称.属性和方法. 其中, 一般类的类名用正常字体粗体表示,如上图:抽象类名用斜体字粗体,如User:接 ...

  8. mount过程分析之六——挂载关系(图解)【转】

    转自:https://blog.csdn.net/zr_lang/article/details/40343899 引言 写到这里我们已经从mount文件系统调用的入口开始,分析到内核的mount,通 ...

  9. MVC与MVVM关系图解

随机推荐

  1. js判断条件为“假”的情况

    以下6种情况判断结果为"假": 1.false(布尔类型) 2.null(用于定义空的或者不存在的引用) 3.undefined(未定义) 4.0(数值0) 5.''(空字符串) ...

  2. linux 系统下 zip 的加密压缩与解压缩命令

    1.加密压缩 [small@sun shine]# zip -rP king java.zip java adding: java/ (stored 0%) adding: java/default/ ...

  3. #333 Div2 Problem B Approximating a Constant Range (尺取 && RMQ || 尺取 && multiset)

    题目链接:http://codeforces.com/contest/602/problem/B 题意 :给出一个含有 n 个数的区间,要求找出一个最大的连续子区间使得这个子区间的最大值和最小值的差值 ...

  4. TTTTTTTTTTTTTT CDOJ Sliding Window 线段树(nlogn)或双端队列(n) 模板

    题目链接: L - Sliding Window Time Limit:6000MS     Memory Limit:131072KB     64bit IO Format:%lld & ...

  5. k8s的node节点,执行kubectl get XXX报错

    报错现象: [root@localhost ~]# kubectl get nodes The connection to the server localhost:8080 was refused ...

  6. 微信浏览器video播放视频踩坑

    video属性介绍 iOS的属性 playsinline On iPhone, video playsinline elements will now be allowed to play inlin ...

  7. 微信小程序访问后台出现 对应的服务器证书无效。控制台输入 showRequestInfo() 可以获取更详细信息。

    检查微信开发者平台配置 https 服务端 nginx 配置 ssl 协议是否有效 在开发者工具中可以使用(详情 > 不校验合法域名.web-view(业务域名).TLS 版本以及 HTTPS ...

  8. ArrayList,Vector ,LinkedList的存储性能和特性

    ArrayList,Vector,LinkedList : 两者都采用数组元素方式存储数据,此数组元素数大于实际存储的数据(以便于增加和插入元素),允许直接按照序号索引元素,但是插入元素涉及数组元素移 ...

  9. 【Python】学习笔记七:函数

    函数的目的:重复使用相同的一段程序 函数的定义 下面是我自定义的一个求a,b,c三个参数平方和的函数 #a,b,c三个参数的平方和 def pow_sum(a,b,c): x = pow(a,2)+p ...

  10. 第一次试验报告&学习总结

    打印输出所有的"水仙花数",所谓"水仙花数"是指一个3位数,其中各位数字立方和等于该数本身.例如,153是一个"水仙花数". 试验代码: p ...