Implementation of Redux and React-redux (iii): the principle of middleware and the realization of Applymiddleware and thunk

Source: Internet
Author: User
Tags redux middleware

Now our redux and react-redux have basically realized, in Redux, trigger a action,reducer immediately can calculate the corresponding state, if I want to let reducer calculate the state after a while? How do we implement an asynchronous action? Middleware (middleware) will be used here

1. Middleware (middleware) Introduction

In the middle is between action and reducer added a layer, no middleware redux process is: action -> reducer , and the process of middleware is action -> middleware -> reducer , using middleware we can be the action is the dispatch method to decorate, We can use it to implement functions such as asynchronous action, print logs, error reporting, and so on.

And the decorator, yes, this piece of things are inseparable from the adorner mode, so the design mode is very important.

As for middleware, there are many frameworks or libraries that use middleware, such as Express, KOA, mongoose and so on.

2. Use of Redux middleware

We can use the Applymiddleware method provided by Redux to use one or more middleware to pass it as the second parameter of CreateStore, we take redux-thunk as an example

import { createStore, applyMiddleware } from ‘redux‘import thunk from ‘redux-thunk‘const store = createStore(counter, applyMiddleware(thunk))ReactDOM.render(  (    <Provider store={store}>      <App />    </Provider>  ),  document.getElementById(‘root‘))

With the thunk middleware, we can implement an asynchronous action.

export function addAsync(){  return dispatch => {    setTimeout(() => {      dispatch(add())    }, 2000);  }}

To implement middleware, we first have two tasks to do:

    1. Extend the CreateStore method so that it can receive the second parameter.

    2. The implementation of the Applymiddleware method.

3. Extension of the CreateStore method

We add a second parameter to the CreateStore enhancer, the professional explanation should be called the enhancer, called middleware also can.

We have already said that the function of middleware is to change the data flow by changing the dispatch method, so we use enhancer to decorate the CreateStore method directly. Redux of the source code is so written, haha haha, how and I think of the exact same? Because I read the source of the redux.

export function createStore (reducer,enhancer) {  if (enhancer) {    return enhancer(createStore)(reducer)  }  let state = {}  let listeners = []  function getState () {    return state  }  function subscribe (listener) {    listeners.push(listener)  }  function dispatch (action) {    state = reducer(state, action)    listeners.forEach(listener => listener())    return action  }  dispatch({type: ‘@myRedux‘})  return {getState, subscribe, dispatch}}

The writing of higher-order functions, should be able to read it? The previous essays have detailed high-order functions, as well as examples.

Implementation of the 4.applyMiddleware method

First look at our call to enhancer, enhancer that is our applymiddleware accept the CreateStore do parameters, returned a function, the function of the parameter is reducer. Now we are no stranger to this two-tier nested function, which is actually a return two layer function.

What does our applymiddleware mainly do? First through the incoming CreateStore method create a store, and then pass the store's dispatch to middleware, by middleware to dispatch packaging, Returns a store with the wrapped dispatch.

It's easy to see here. But notice, remember how we used the asynchronous action?

export function addAsync(){  return (dispatch, getState) => {    setTimeout(() => {      dispatch(add())    }, 2000);  }}

Incredibly can also be in the asynchronous action to get dispatch and GetState methods, so to deal with this, it is not very difficult to pass them both to our middle just fine.

It's all here, can you write it yourself?

export function applyMiddleware (middleware){    return createStore => (...args) => {        const store = createStore(...args)        let dispatch = store.dispatch        const midApi = {            getState: store.getState,            dispatch: (...args)=>dispatch(...args)        }        dispatch = middleware(midApi)(store.dispatch)        return {            ...store,            dispatch        }    }}

If we execute the wrapped dispatch, it is equivalent to executing middleware(midApi)(store.dispatch)(action) this statement, which is a three-layer nested function, which we also call the curry.

5. Own Redux-thunk

In fact, their thunk is very simple, the return value of the normal action is an object, as previously said, the return value of the asynchronous action is a function, then we just need to determine the type of action return.

const thunk = ({dispatch, getState}) => next => action => {    if (typeof action === ‘function‘) {        return action(dispatch, getState)    }    return next(action)}export thunk

Here, dispatch and GetState are the MIDAPI objects that we passed into the Applymiddleware, Next is Store.dispatch can also be understood as the next middleware, if the type of action is an object, indicating that this is a synchronous, direct dispatch just fine, if
The type of action is function, and when this dispatch is triggered, the action is triggered, and the dispatch and GetState methods are passed into the action function. This is why we can get the dispatch and GetState methods in an asynchronous action.

6. Multiple middleware merging and compose methods

Our Applymiddle method is not too perfect, can only use a middleware, the use of multiple middleware to do, this, simple, map a chant. What if multiple middleware is required to do this? or map, OK, here's a map.

We'll get the code like this:

const store = createStore(    reducer,    applyMiddleware(middlewareOne) (        middlewareTwo(          middlewareThree(              ...          )        )    ))

We will find that we are trapped in a deep nested function, and we need a compose method to combine it to facilitate our writing.

Compose is a form of functional programming, and the function of compose is to combine multiple functions from right to left, forming a final function. It is the form fn1(fn2(fn3())) that becomes the form of compose (Fn1, fn2, Fn3).

What compose does is that you avoid the right offset of the code when you write deep nested functions. Don't think it's complicated.

Implementation of the Compose method:

export function compose (...funcs){    if (funcs.length==0) {        return arg=>arg    }    if (funcs.length==1) {        return funcs[0]    }    return funcs.reduce((ret,item)=> (...args)=>{                console.log(ret)       return ret(item(...args))      })}

Compose is not so complicated, if you want to learn more about compose, you can see Redux's description of compose.

Here we can use multiple middleware Applymiddleware method has been implemented, the entire Applymiddleware method here:

  export function applymiddleware (... middlewares) {return createstore=> (... args) =>{const store            = CreateStore (... args) let dispatch = Store.dispatch Const MIDAPI = {GetState:store.getState,             Dispatch: (... args) =>dispatch (... args)} const Middlewarechain = Middlewares.map (middleware=>{ Return middleware (MIDAPI)}) Console.log (Compose (... middlewarechain) (store.dispatch)) dis Patch = Compose (... middlewarechain) (Store.dispatch) return {... store, dispatch}}        }export function Compose (... funcs) {if (funcs.length==0) {return arg=>arg} if (funcs.length==1) { Return Funcs[0]} return Funcs.reduce ((ret,item) = (... args) =>{console.log (ret) Retu RN RET (item (... args))})}  

Here, the whole redux and react-redux of the basic principles we have been clear, has been basically implemented, found that it involves a lot of functional programming and decorator mode, there is an observer pattern, so, programming ideas and design patterns is very important, there is time to strengthen this aspect of learning.

We now have these foundation, can go to see Redux and React-redux source code, also basically and I write is similar, because I also read the source code.

Implementation of Redux and React-redux (iii): the principle of middleware and the realization of Applymiddleware and thunk

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.