Redux中间件 #

redux

1. 编写redux #

src/redux.js

const createStore = (reducer) => {
    let state;
    let listeners = [];

    const getState = () => state;

    const dispatch = (action) => {
        state = reducer(state, action);
        listeners.forEach(listener => listener());
    };

    const subscribe = (listener) => {
        listeners.push(listener);
        return () => {
            listeners = listeners.filter(l => l !== listener);
        }
    };

    dispatch({});

    return { getState, dispatch, subscribe };
};
export {createStore}

src/index.js

import React from 'react';
import {createStore} from './redux';

let reducer = (state=0,action)=>{
    if(action){
        switch(action.type){
            case 'add':
                return state +1;
            case 'sub':
                return state -1;
            default:
                return state;
        }
    }else{
        return state;
    }
}
let store = createStore(reducer);
store.subscribe(()=>{
    alert(store.getState());
})store.dispatch({type:'add'});

2. 实现applyMiddleware #

src/redux.js

let applyMiddleware = (middleware) => (createStore) => (reducer) => {
  let store = createStore(reducer);
  let dispatch = store.dispatch;
  middleware = middleware({getState:store.getState,dispatch:(action)=>dispatch(action)});
  dispatch = middleware(store.dispatch);
  return {...store, dispatch}
}

export {createStore, applyMiddleware}

src/index.js

import {createStore, applyMiddleware} from './redux';
let logger = store => next => action => {
    console.log('before', store.getState());
    next(action);
    console.log('after', store.getState());
}
let store = applyMiddleware(logger)(createStore)(reducer);
store.subscribe(() => {
    console.log(store.getState());
 })

3. 使用redux-thunk实现异步操作 #

src/index.js

let thunk = ({ dispatch,getState}) => next => action =>{
  if(typeof action == 'function')
       return action(dispatch,getState);
   next(action);
}

4. 使用redux-promise实现异步操作 #

src/index.js

let isPromise = (obj)=> obj.then;
let promise =  {dispatch} => next => action =>{
 return isPromise(action)?action.then(dispatch):next(action);
}

store.dispatch(new Promise(function(resolve,reject){
 setTimeout(function(){
   resolve({type:'add'});
 },2000)}));

5. 使用多个中间件 #

src/redux.js

let applyMiddleware = (...middlewares) => createStore => reducer => {
        let store = createStore(reducer);
        let dispatch = store.dispatch;
        middlewares = middlewares.map(middleware=>middleware({getState:store.getState,dispatch:action=>dispatch(action)}));
        dispatch = compose(...middlewares)(store.dispatch);
        return {...store, dispatch}
}

function compose(...funcs) {
    return args => funcs.reduceRight((composed, f) => f(composed), args);
}

src/index.js

let logger1 = store => next => action => {
    console.log('before1', store.getState());
    next(action);
    console.log('after1', store.getState());
}
let logger2 = store => next => action => {
    console.log('before2', store.getState());
    next(action);
    console.log('after2', store.getState());}
let store = applyMiddleware(logger2,logger1)(createStore)(reducer);

参考代码 #