Redux
纯函数
- 确定的输入,一定会有确定的输出
- 函数执行过程中,不能有副作用
副作用:
执行一个函数时除了返回函数值之外,还对调用函数产生了附加的影响,比如修改了全局变量
,修改参数或改变外部的存储
Store=>state
数据存储的地方
Action=>修改state
所有数据的变化必须通过dispatch action来更新
action是一个普通的js对象,用来描述这次更新的type和content
reducer=>纯函数
- reducer是一个纯函数
- 将传入的state和action结合起来生产一个新的state
代码优化
- 将派发的action生产过程放到一个actionCreators函数中
- 将定义的所有actionCreators函数,放到一个独立的文件中: actionCreators.js
- actionCreators和reducer函数中使用字符串常量是一致的,所有将常量抽取到一个独立的constants的文件中
- 将reducer和默认值(initalState)放到一个独立的reducer.js文件中,而不是在index.js中
- index.js用于创建store和导出store
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
| const { ADD_NUMBER, CHANGE_NAME } = require("./constant")
const changeNameAction = (name) => ({ type: CHANGE_NAME, name })
const addNumberAction = (num) => ({ type: ADD_NUMBER, num })
module.exports = { changeNameAction, addNumberAction } --------------------------------------------------------------------------------
const ADD_NUMBER = "add_number" const CHANGE_NAME = "change_name"
module.exports = {ADD_NUMBER, CHANGE_NAME}
const { ADD_NUMBER, CHANGE_NAME } = require("./constant")
const initialState = { name: "why", num:100 }
function reducer(state = initialState, action) { console.log(state, action); switch(action.type) { case CHANGE_NAME: return { ...state, name: action.name} case ADD_NUMBER: return {...state, counter: state.counter + action.num} default: return state } }
module.exports = {reducer}
const store = require("./store") const { addNumberAction, changeNameAction} = require("./store/actionCreators")
const unsubscribe = store.subscribe(() => { console.log("订阅数据的变化",store.getState()) })
store.dispatch(changeNameAction("curry"))
|
Redux的三大原则
单一数据源
- 整个应用程序的state被存储在一颗Object tree中, 并且这个object tree只存储在一个store中
- Redux并没有强制让我们不能创建多个Store,但是那样做并不利于数据的维护
- 单一的数据源可以让整应用程序的state变得方便维护,追踪,修改
State是只读的
- 唯一修改State的方法一定是触发action,不要试图在其他地方通过任何方式来修改State
- 这样确保了View或网络请求都不能直接修改state,它们只能通过action来描述自己想要如何修改state
- 这样可以保证所有的修改都被集中化处理,并且按照严格的顺序来执行,所有不需要担心race condition的问题
使用纯函数来执行修改
- 通过reducer将旧state和actions联系在一起,并且返回一个新的State
- 随着应用程序的复杂度增加,我们可以将reducer拆分成多个小的reducers,分别操作不同的state tree的一部分
- 但是所有的reducer都应该是纯函数,不能茶是你任何副作用