Redux知识点
基本知识点
-
store
容器,保存数据的地方,整个应用只能有一个 -
store.getState()
获取store快照,即执行时store数据的集合 -
action
state
和view
是同步的,state
改变view
也会发生变化,然而用户操作都是在view
进行的,所以就需要用到了action
,表示view
发出通知来修改state
我们约定action
内必须使用一个字符串类型的type
字段来表示将要执行的动作 -
Action Creator
方便用来创建
action
.:const ADD_TODO = '添加 TODO'; function addTodo(text) { return { type: ADD_TODO, text } } const action = addTodo('Learn Redux');
addTodo 就是一个action creator
-
store.dispatch()
view
发出action
的方法store.dispatch(action)
将使用当前
getState()
的结果和传入的action
以同步方式的调用store
的reduce
函数。它的返回值会被作为下一个state
。 -
reducer
纯方法!!store
收到action
后便需要改变state
,然后对应的view
才会发生变化。由此便需要reducer
函数来完成该操作.
用来将action
更新过的state
与更新前的state
合并(其实是更新值覆盖)Reducer
方法是由store.dispatch
方法触发来自动执行的reducer
函数的第一个参数为当前的state
,第二个参数为action
const reducer = function (state, action) { // ... return new_state; }
Reducer 函数里面不能改变 State,必须返回一个全新的存储
state
的对象 -
subscribe(callback)
设置监听函数,参数为回调函数,一旦state
发生改变,便会执行回调函数。
所以: 只要把 View 的更新函数(对于 React 项目,就是组件的render
方法或setState
方法)放入listen,就会实现 View 的自动渲染
而 subscribe() 执行会返回一个函数,习惯上可以命名为unsubscribe
,没有规定。而执行这个unsubscribe
函数就会解除监听函数let unsubscribe = store.subscribe(() => console.log(store.getState()) ); unsubscribe();
-
combineReducers()
望文生义,使reducer
结合到一起。即将各个子reducer
合并成一个大的reducer
合并后的reducer
可以调用各个子reducer
,并把它们返回的结果合并成一个state
对象。
参数: 一个Object对象,key为 reducerName 可以自定义,value为 reducer函数
返回值: 调用所有传入的reducer
,即传入参数对象的 value 值。返回和传入参数结构一致的state
对象reducers/index.js
function todo(state=0,action){ switch(action.type){ case('ADD'): return state+1; default: return state; } } function say(state='say',action){ switch(action.type){ case('ENGLISH'): return state+'english' default: return state; } } const reducers = combineReducers({ todo, say }) moudle export reducers;
app.js
import { createStore } from 'redux'; import reducers from './reducers/index.js'; let store = createStore(reducers); console.log(store.getState()); //{ // todo: 0, // say: 'say' //} store.dispatch({ type: 'ADD' }) console.log(store.getState()); //{ // todo: '1', // say: 'say' //}
-
connect(mapStateToProps,mapDispatchToProps,)
连接 React 组件与 Redux store。
连接操作不会改变原来的组件类。
反而返回一个新的已与 Redux store 连接的组件类。
将store
中的state
和dispatch
绑定到子组件上,使子组件可以通过props
获取到。
任何时候,只要 Redux store 发生改变,mapStateToProps
函数就会被调用 -
bindActionsCreators()
是通过dispatch
将action
包裹起来,这样可以通过bindActionCreators
创建的方法,直接调用dispatch(action)
(隐式调用),相当于直接组合成dispatch({type:type.ADD_ITEM, text})
这种形式。
用法:let newAction = bindActionCreators(oldActionCreator,dispatch) <child {...newAction}/>>
以上代码将
dispatch
和action
组合成的对象直接传给了子组件,然后在子组件中就可以 通过调用newAction.action1
就相当于实现了dispatch(action1)
由此便实现了在没有store
和dispatch
的组件中调用dispatch(action1)
-
Middleware
Middleware 接收了一个 next() 的 dispatch 函数,并返回一个 dispatch 函数,返回的函数会被作为下一个 middleware 的 next(),以此类推 -
applyMiddleware(…middlewares)
该函数返回一个柯里化的函数,所以调用这个函数应该这样写applyMiddleware(...middlewares)(createStore)(...args)
源码:function applyMiddleware(...middlewares) { // 这里执行 createStore 函数,把 applyMiddleware 函数最后次调用的参数传进来 return createStore => (...args) => { const store = createStore(...args) let dispatch = () => { throw new Error( `Dispatching while constructing your middleware is not allowed. ` + `Other middleware would not be applied to this dispatch.` ) } // 每个中间件都应该有这两个函数 const middlewareAPI = { getState: store.getState, dispatch: (...args) => dispatch(...args) } // 把 middlewares 中的每个中间件都传入 middlewareAPI const chain = middlewares.map(middleware => middleware(middlewareAPI)) // 从右至左调用每个中间件,然后传入 store.dispatch dispatch = compose(...chain)(store.dispatch) // 返回store和最后的dispatch return { ...store, dispatch } } }
-
compose(…functions)
函数式编程方法,参数为多个函数,将多个函数组合为最终一个函数,即 自右向左前面一个函数的返回值作为参数传入左面一个函数 以此类推compose(funcA, funcB, funcC)
<=>funcA(funcB(funcC()))
源码:function compose(...funcs) { if (funcs.length === 0) { return arg => arg } if (funcs.length === 1) { return funcs[0] } return funcs.reduce((a, b) => (...args) => a(b(...args))) }