Redux
Redux 对于通信工程专业的来说可以这么理解
在不用Redux的时候,组件中的信息传递就好像我通过用嘴巴说的方式向你传递信息,但是当周围环境比较嘈杂信息比较多或者我距离你比较远的时候,信息的传递就比较费劲了,一句两句还好,多了肯定会很累。
那么Redux是个什么存在呢?他就像一个基站,我和大家的所有数据传递都用手机打给你的手机,然而手机与手机之间的信息传递不是 手机 <-----> 手机这样的。
而是 手机 <----> 基站 <----> 手机 这样的关系。
而 Redux对于整个单页来说就有点像基站的存在,所有数据统一通过Redux来进行管理。
Redux的出现是为了让应用当中所有动作和状态统一管理,让一切有据可循。
Store
store与state的区别,state是应用的一个状态,本质上来说他是一个普通对象。
而store是state对象的一个管理者,包含下面四个函数
getState() # 获取整个 state
dispatch(action) # ※ 触发 state 改变的【唯一途径】※
subscribe(listener) # 您可以理解成是 DOM 中的 addEventListener
replaceReducer(nextReducer) # 一般在 Webpack Code-Splitting 按需加载的时候用
state和store存在这种关系:
var state = store.getState();
在Redux当中规定,一个应用只有单一的store,并且不能直接修改store当中的state
var state = store.getState() state.counter = state.counter + 1 // 禁止在业务逻辑中直接修改 state
改变store当中的state只能通过dispatch一个action来进行,这个是修改应用状态的唯一方法
就好像你不能直接和基站说你要发短信,发QQ消息,打电话给谁谁谁,这个肯定是行不通的。
你需要通过手机来选择具体的操作,你需要发送短信,就打开短信工具,然后发送短信。需要打电话就打开通讯录选择对方打过去。需要发送QQ视频就打开QQ发送视频。
这些具体的动作就是action,你需要选择一个具体的动作然后发送信息,然后基站才能通过这些具体的动作来执行,达到目的。
那么store是怎么来的呢?
你需要一个基站,那么基站如何知道怎么处理你发送过来的各种不同的信息,并且做出正确的处理呢?
这个就需要你在设计制造这个“基站”的时候根据你的需求来设计出一个具体的处理方案。
这个时候就需要一个 createStore ,这个就是制造“基站”的工厂。
调用createStore传入一个reducer来生成一个store.
reducer就好像是你的设计图,你把这个设计图给一个叫 reducer 的代工厂,这个代工厂就会根据你的设计图来给你制作出一个特制的基站,用来处理你的各种数据操作。
import { createStore } from 'redux' ... const store = createStore(reducer, initialState) // store 是靠传入 reducer 生成的哦!reducer
是一个 函数,负责更新并返回一个新的state
而initialState
主要用于前后端同构的数据同步(详情请关注 React 服务端渲染)
Action
实质上是一个包含type属性的普通对象,这个type是store这个基站用来识别用户行为的关键。
{ type: 'ADD_TODO', // 发短信,打电话,发送qq视频,发送qq消息... payload: { //发送的信息, QQ消息,语音消息。。。。 id: 1, content: '待办事项1', completed: false } }
Action当中的信息只用type是必须要的,其他的数据可以是任意的。
Action Creator
Action Creator 是 action
的创造者,本质上就是一个函数,返回值是一个 action
(对象)
var id = 1 function addTodo(content) { return { type: 'ADD_TODO', payload: { id: id++, content: content, // 待办事项内容 completed: false // 是否完成的标识 } } }
这样就不需要每次有新的相同行为的时候都重新定义一个了,直接使用action creator来生成传入变量即可
Reducer
用户每次 dispatch(action)
后,都会触发 reducer
的执行reducer
的实质是一个函数,根据 action.type
来更新 state
并返回 nextState
最后会用 reducer
的返回值 nextState
完全替换掉原来的 state
var initState = { counter: 0, todos: [] } function reducer(state, action) { // ※ 应用的初始状态是在第一次执行 reducer 时设置的 ※ if (!state) state = initState switch (action.type) { case 'ADD_TODO': var nextState = _.cloneDeep(state) // 用到了 lodash 的深克隆 nextState.todos.push(action.payload) return nextState default: // 由于 nextState 会把原 state 整个替换掉 // 若无修改,必须返回原 state(否则就是 undefined) return state } }
通俗点讲,就是 reducer
返回啥,state
就被替换成啥
总结
-
store
由 Redux 的createStore(reducer)
生成 -
state
通过store.getState()
获取,本质上一般是一个存储着整个应用状态的对象 -
action
本质上是一个包含type
属性的普通对象,由 Action Creator (函数) 产生 -
改变
state
必须dispatch
一个action
-
reducer
本质上是根据action.type
来更新state
并返回nextState
的函数 -
reducer
必须返回值,否则nextState
即为undefined
-
实际上,
state
就是所有reducer
返回值的汇总