if 读完了 then 你能了解到:vue
- 好钢用在刀刃 - redux的应用场景
- 万变不离其宗 - redux的基本思路
最近有个任务,就是须要在一个开源项目上进行扩展开发,而这个开源项目用到的是很是主流的 react 和 react-redux,近些年一直在跟 vue 打交道(广告植入:好比开源了一个 vue 版本的 ncform 项目),冷落了 react 有一段时间了,恰好趁机重温下 react 及其周边相关的技术生态java
react-redux,其实就是 redux 的 react 版本,方便 redux 在 react 中使用。react
而 redux,是 javaScript 应用状态管理容器,是参考 flux 设计模式的一种实现(vue 的 vuex 也是相似的实现),它独立于各类 web 框架但又可融入于各类 web 框架。git
不少人会认为,引入 redux 会增长应用的复杂性。确实不简单,但存在即合理,因此什么场景下适合使用 redux 就很关键了。github
我就开发一个活动页。奉劝你不要用 redux 啦,一点好处都没有,只会增长复杂性。web
切记:不要为了用而用 - 然而现实中这种现象是大量存在的vuex
当一个应用的功能愈来愈多时,开始进行功能模块拆分,这个时候,就会遇到一个问题,功能模块之间共享的数据如何处理,好比登陆用户的信息。redux
例子能再具体点吗?好吧,但仍是登陆用户信息,哈哈。设计模式
好比你在用户模块修改了头像,而后顶栏上的登陆头像要实时跟着更新,这个时候,实际上是用户模块和顶栏共享了你的用户头像信息api
解决这种可能有N种方法,今天既然聊 redux,那就专心讲它吧
当你把数据梳理一下,你会发现有些数据是在模块内共享的,有些数据是在模块间共享的,咱们将在模块间共享的称之为应用级别的数据,即 Application 级别,redux 就是专门处理这种级别数据的解决方案
咱们用 redux 官方的 todo app 例子来说解( Warning: 仅为了说得简单,讲得明白,这种小应用是不适合引入 redux 的 )
你的应用有着一份描述着状态(state)的数据,可能以下:
🔸 术语
State: 应用级别的状态数据
{
todos: [{
text: 'Eat food',
completed: true
}, {
text: 'Exercise',
completed: false
}],
visibilityFilter: 'SHOW_COMPLETED'
}
复制代码
这份 state 是静态的,你能够理解为就是应用最初的状态。
当我完成了 Exercise
项,我就打个勾,表示我完成了。此时就须要更改下应用的状态,须要把 Exercise
那一项 的completed
由 false 改为 true。
怎么更改呢?直接把值改了不就完事了?
若是直接改变 state 对象的属性值,就断了 state 更改的轨迹,简单讲就是你修改了一个对象的属性值,你就很难追踪属性值更改前是什么样子了。这在调试排查问题的时候很是有用。
必定有更好的方法,可参考下事件的机制。因此当想更改状态时,咱们派发(dispath)一个操做(action),描述清楚咱们想干什么,而不是直接就干了。一个操做的描述可能以下:
{ type: 'ADD_TODO', text: 'Go to swimming pool' }
{ type: 'TOGGLE_TODO', index: 1 }
{ type: 'SET_VISIBILITY_FILTER', filter: 'SHOW_ALL' }
复制代码
🔸 术语
dispatch: 经过该方法主动派发操做
action: 描述操做的内容,type
值必须提供,指定行为的类型,至关于事件的名称
用派发操做的好处:
将每一个更改描述为一个操做,让咱们清楚地了解应用程序中发生的状况。 若是发生了变化,咱们就知道它为何会改变,操做就像面包屑,使得应用状态的变化有迹可循
OK,至此啥事还没作,只是嘴上嚷嚷我要作什么,那总得有实际处理的方法吧。
没错,这些实际修改状态的方法称为 reducer。实现可能以下:
function visibilityFilter(state = 'SHOW_ALL', action) {
if (action.type === 'SET_VISIBILITY_FILTER') {
return action.filter
} else {
return state
}
}
function todos(state = [], action) {
switch (action.type) {
case 'ADD_TODO':
return state.concat([{ text: action.text, completed: false }])
default:
return state
}
}
复制代码
🔸 术语
reducer:它负责接收当前 state 和 action,而后按照 action 的 type,根据当前 state 进行操做,最终返回一个全新的 state(返回全新的 state 保证了 数据修改的可追溯性)。
你会发现 visibilityFilter
返回的是查询条件字符串,而 todos
返回的是列表项数组列表。把它们返回的数据合并起来,就是一个完整的应用状态,以下:
function todoApp(state = {}, action) {
return {
todos: todos(state.todos, action),
visibilityFilter: visibilityFilter(state.visibilityFilter, action)
}
}
复制代码
OK,到此为此,想干什么也说了,实际作事的也讲了,但好像仍是云里雾里,脑壳里依然没有很清晰的全局的画面,好像还少了什么东西。
告诉你,少了一个管家,它管着应用的状态,它就是 store。
🔸 术语
Store: 管理应用状态数据,负责把 action, reducer 等串起来
咱们借用 redux 的一些 api 来完整描述一个数据修改的全过程
let store = createStore(todoApp)
复制代码
function listener() { console.log(store.getState()) }
store.subscribe(listener)
复制代码
let action = { type: 'ADD_TODO', text: 'Go to swimming pool' }
store.dispatch(action)
复制代码
😫修改了好屡次,终于写完了。。。
接下来的内容跟本文一毛钱关系都没,只是一如既往地打一波广告:
ncform,一种使人愉悦的表单开发方式,仅需配置便可生成表单UI及其交互行为。
自带丰富的 标准组件 和 校验规则,开箱即用。
具有强大的 控件交互 和 扩展能力,作你所想。
github: github.com/ncform/ncfo…
注:目前只有 vue 版本,但愿在不久的未来,有时间发布 react 版本
tags: react, flux, react-redux, redux