# redux基础
- react本身是一个非常轻量级的视图层框架,想要构建大型应用,必须配套一个数据层框架
- redux=reducer+flux,
- redux的设计理念:把数据放到一个公共的数据管理区域store中管理,一个组件改变了store中的数据,其他组件就感知到store的变化,再来取数据,从而间接实现来组件间传递数据的功能
# redux的工作流程
- React Component 借书的人
- Action Creator 要借什么书,说的这句话
- action 是一个对象,有一个type属性
- Store 图书馆管理员
- state 三个特点,1)唯一的数据源 2)只读,改变state 的唯一方式是触发一个action 3)改变发生在reducer,是一个纯函数,是返回一个新的state,而不是修改旧的
- Reducers 记录本
- reducer 是一个pure function,reducer中可以接收state,但绝不能改变state
- react中要改变state中的数据,首先要调用actionCreator创建一个action, action会通过dispatch方法传递给store,store再把之前的数据和action转发给reducer,reducer是一个纯函数,它接收到state和action之后呢,做一些处理之后,会返回一个新的state给到store,store用新的state替换掉之前的state数据,store数据发生改变时,react组件可以感知到store数据的改变,这个时候它从store中重新取数据,更新组件内容,页面就跟着更新了
# 拆分actionTypes
- 方便排错,字符串写错不会报错,而变量写错会报错
# 使用actionCreator统一创建action
- 提高代码的可维护性
- 有利于前端的自动化测试
# Redux设计和使用的三大原则
- store是唯一的
- 只有store能够改变自己的内容,
- 不要误认为是reducer更新store中的数据,实际是store拿到reducer返回的数据,自己对自己的数据进行一次更新,reducer只可以接收state,但绝不能修改state
- reducer必须是个纯函数,
- 纯函数指的是,给定固定的输入,就一定会有固定的输出,而且不会有任何副作用
- 一旦函数中有setTimeout,ajax请求,或者和日期相关的内容时,它都不再是一个纯函数了,所以reducer中不能有异步操作,也不能有跟日期时间相关的操作
- 对传入的参数,进行了修改,即产生了副作用,这样也就不是纯函数了
# Redux的核心API
- createStore, 可以帮助我们创建一个store
- store.dispatch, 帮助我们派发action,这个action会传递给store
- store.getState, 可以帮助我们获取到store中所有的数据内容
- store.subscribe, 可以让我们订阅store的改变,当store发生改变,store.subscribe()接收的回调函数就会被执行
# 手写简版redux
export function createStore(reducer, enhancer) {
if (enhancer) {
return enhancer(createStore)(reducer);
}
let currentState = undefined;
let currentListeners = [];
function getState() {
return currentState;
}
function dispatch(action) {
currentState = reducer(currentState, action);
currentListeners.map(lis => lis());
return action;
}
function subscribe(listener) {
currentListeners.push(listener);
}
dispatch({ type: "IMMOCC/KKKREDUX" });
return {
getState,
dispatch,
subscribe,
};
}
export function applyMiddleware(...middlewares) {
return createStore => (...args) => {
const store = createStore(...args);
const midAPi = {
getState: store.getState,
dispatch: store.dispatch,
};
const middlewareChain = middlewares.map(mw => mw(midAPi));
const dispatch = compose(...middlewareChain)(store.dispatch);
return {
...store,
dispatch,
};
};
}
function compose(...funcs) {
const len = funcs.length;
if (len === 0) {
return arg => arg;
} else if (len === 1) {
return funcs[0];
} else {
return funcs.reduce((a, b) => (...args) => b(a(...args)));
}
}