Action

具有type属性的对象,store唯一数据来源(使用dispatch分发)
创建函数
返回一个action


Reducer


dispatch后执行,执行所有的子reducer,recuer且都为纯函数,没有副作用
首次执行,state为undefined,可设置默认值

拼接所有的reducer形成新的state
combineReducers

Store

纯正的store只接受对象类型的action,且立即进行reducer的处理
使用applyMiddleware套住createStore,中间件将修改action的执行,例如thunk执行异步请求

subscribe(listener)

注册监听,注意嵌套的dispatch使用

==================================

使用connect
自定义mapStateToProp:容器组件通过props提供给展示组件需要从store里面拿到的state
自定义mapDispatchToProps: 容器组件通过props提供给展示组件操作state的含有dispatch的函数

==================================
thunk: action创建函数, 可以return 一个函数,参数为dispatch,让它自己能做dispatch
异步Action:根据状态来dispatch多种同步的action, 可以使用action的type附加标记位,也可以附加额外属性

两者结合:
function asyncAction(params) {
return ((dispatch ,getstate())=> {
dispatch(request(params))
return fetch(url)
.then(res => res.data)
.then(data => dispatch(receive(data)))
})
}
thunk如何创建该reducer相关action状态 ?

中间件Middleware
每一个中间件都操纵的是前一个包装过后的dispatch
function logger(store) {
return function wrapDispatchToAddLogging(next) {
return function dispatchAndLog(action) {}}}
与官方的三个区别:

  • 它只暴露一个 store API 的子集给 middleware:dispatch(action)getState()
  • 中间件里面应该使用next(action)而不涉及store.dispatch(action),会导致遍历所有的中间件
  • 因此它的签名不是 (store, middlewares) => store, 而是 (…middlewares) => (createStore) => createStore。

异步请求中间件
export function loadPosts(userId) {
return { // 要在之前和之后发送的 action types
types: [‘LOAD_POSTS_REQUEST’, ‘LOAD_POSTS_SUCCESS’, ‘LOAD_POSTS_FAILURE’], // 检查缓存 (可选): shouldCallAPI: (state) => !state.users[userId], // 进行取:
callAPI: () => fetch(http://myapi.com/users/${userId}/posts), // 在 actions 的开始和结束注入的参数 payload: { userId }
}; }

cosnt callApiMiddleWare = store => next => action => {
const [ requestType, successType, failureType ] = types
dispatch(Object.assign({}, payload, { type: requestType }))
return callApi(url).then( res =>
dispatch(Object.assign({}, payload, { res , type: successType}))
), error => {
dispatch(Object.assign({}, payload, { error , type: successType}))
}
}

Reducers 生成器

===============================

计算衍生数据,创建记忆性的selector

只在对应state或者查询参数发生变化时重新计算。
getVisibleTodos = createSelector( [ getVisibilityFilter, getTodos ], (visibilityFilter, todos) => {
switch (visibilityFilter) {
。。。。
default: return todos
} }
而getVisibleTodos可以通过mapStateToProps接受props, 然后getVisibilityFilter(state,props)

跨多组件的共享 Selector

需要包装一层组件私有的selector

==========================

实现撤销历史

{ past: Array, present: T, future: Array }
undo redo 处理其他action
可以分离历史记录

Reducer Enhancers

function combineReducers(reducers) {
return function (state = {}, action) {
return Object.keys(reducers).reduce((nextState, key) => {
// 调用每一个 reducer 并将其管理的部分 state 传给它
nextState[key] = reducerskey
return nextState
}, {}) } }

可以记录state的历史,保证原有的reducer进行处理,并附加对状态的额外记录操作

=================

bindActionCreators(actionCreators, dispatch)

传递给不想深入接触redux的子组件
返回 use(params) 等于 dispatch(actionCreate(params))

compose(…functions)

函数式编程的方法, 从右往左,把前一个函数的返回作为下一个的参数,最终合成一个函数,最右边可接受更多参数
柯里化”,就是把一个多参数的函数,转化为单参数函数。

子应用隔离

大组件包裹多个小组件,小组件自身完全独立,可使用单独的store树,相当于黑盒
子组件之间不能共享数据