Redux is a state management library that is not directly related to other frameworks such as React, so redux can be used in other environments without React. Because there is no logical coupling with React, the redux source code is pure, with the goal of managing data well. To use Redux in react projects, you need a React-Redux connector to connect React to Redux.

Before I read the redux source code, I thought it would be difficult to read Redux because I was overwhelmed by the many concepts of Redux when I first learned how to use it. When you actually look at the redux source code, you’ll find that the redux source code content is relatively small, the amount of code is relatively small, and the quality of the code is quite high, so it is well worth looking at the source.

The directory structure

You can skip the other directories and just look at./ SRC:

.\REDUX\SRC │ applyMiddleware.js │ bindActionCreators.js │ combineReducers.js │ compose.js │ createStore.js │ index.js │ └─utils actionTypes.js isPlainObject.js warning.js

Index.js aggregates and exposes applymiddleware.js. Utils just puts some helper functions in it. So there are only five files to look at, and those are the five apis exposed by Redux.

// index.js
import createStore from './createStore'
import combineReducers from './combineReducers'
import bindActionCreators from './bindActionCreators'
import applyMiddleware from './applyMiddleware'
import compose from './compose'
import warning from './utils/warning'
import __DO_NOT_USE__ActionTypes from './utils/actionTypes'

// Ignore the content

export {
  createStore,
  combineReducers,
  bindActionCreators,
  applyMiddleware,
  compose,
  __DO_NOT_USE__ActionTypes
}
Copy the code

compose.js

This is the only function of the five apis that can be used separately. It is a composite function that is commonly used in functional programming. It has nothing to do with Redux itself, but to understand some concepts of functional programming:

A pure function is one in which the same input always returns the same output without any observable side effects. Code combination

Code:

export default 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))) }Copy the code

For compose, var a = compose(fn1,fn2,fn3,fn4)(x))))) = compose(fn1,fn2,fn3,fn4).

Redux’s compose implementation is simple and uses the array reduce method, which can be used in MDN.

Return funcs.reduce((a,b) => (.. args) => a(b(… args)))

I often write reduce functions, but I’m a little confused by this code, so here’s a practical example of how this function works:

import {compose} from 'redux'
let x = 10
function fn1 (x) {return x + 1}
function fn2(x) {return x + 2}
function fn3(x) {return x + 3}
function fn4(x) {return x + 4}

// Suppose I wanted to find something like this
let a = fn1(fn2(fn3(fn4(x)))) // 10 + 4 + 3 + 2 + 1 = 20

For compose, we can change the composition to the following:
let composeFn = compose(fn1, fn2, fn3, fn4)
let b = composeFn(x) // In theory you should get 20
Copy the code

For compose(fn1, fn2,fn3, fn4), compose(fn1, fn2,fn3, fn4), [fn1,fn2,fn3, fn4]. Reduce ((a, b) => (… args) => a(b(… args)))

Number of cycles The value of a The value of b The value returned
First cycle fn1 fn2 (… args) => fn1(fn2(… args))
Second cycle (… args) => fn1(fn2(… args)) fn3 (… args) => fn1(fn2(fn3(… args)))
Third cycle (… args) => fn1(fn2(fn3(… args))) fn4 (… args) => fn1(fn2(fn3(fn4(… args))))

The return value at the end of the loop is (… args) => fn1(fn2(fn3(fn4(… The args)))). So after the compose process, the function should be in the desired format.

conclusion

The compose function is common in functional programming. Redux’s compose implementation is simple, but not easy to understand, mainly because of its lack of fluency with array.prototype. reduce functions, and also because of the way the receiver function returns a function with successive =>.

This is the first of redux’s readings, and I’m going to cover a couple of apis. In particular, the applyMiddleware API uses compose to compose middleware, which is a bit of a puzzle.