Introduction to the

Redux is a state container for JavaScript applications, providing predictable state management. Not bound to any UI library.

Redux Flow

The flow chart

Flow Gif

Core API Exploration

Core API List

@redux/src/index.ts

Export {createStore, // Create the root Store; CombineReducers is used to create functions such as Dispatch to operate objects in the closure. // Associate multiple Reducer partitions commonly used in large applications, bindActionCreators, applyMiddleware, // Middleware logic compose, // encapsulation of multiple fuC's in series __DO_NOT_USE__ActionTypes}Copy the code

Redux.createStore

Create root Store; With closures, functions such as Dispatch are created to operate on objects inside the closure

Core code:

/**
 * Creates a Redux store that holds the state tree.
 * The only way to change the data in the store is to call `dispatch()` on it.
 *
 * There should only be a single store in your app. To specify how different
 * parts of the state tree respond to actions, you may combine several reducers
 * into a single reducer function by using `combineReducers`.
 *
...
const store = {
    dispatch: dispatch as Dispatch<A>,
    subscribe,
    getState,
    replaceReducer,
    [$$observable]: observable
  } as unknown as Store<ExtendState<S, StateExt>, A, StateExt, Ext> & Ext
  return store
Copy the code

An application would theoretically only use createStore once; all remaining operations would be performed on the root Store that createStore gets.

Store.dispatch

Function: The only way to change a store

Core code:

function dispatch(action: A) {if (isDispatching) {throw new Error('Reducers may not dispatch actions.')} try {A) {if (isDispatching) { isDispatching = true currentState = currentReducer(currentState, State} finally {isDispatching = false} const Listeners = (currentListeners = NextListeners) for (let I = 0; i < listeners.length; i++) { const listener = listeners[i] listener() } return action }Copy the code

Store.getState

Function: Obtain the latest state image

/** * Reads the state tree managed by the store. * * @returns The current state tree of your application. */ function getState(): S { if (isDispatching) { throw new Error( 'You may not call store.getState() while the reducer is executing. ' + 'The reducer has already received the state as an argument. ' + 'Pass it down from the top reducer instead of reading it from  the store.' ) } return currentState as S }Copy the code

Store.subscribe

Function: Register to listen for state changes. Return unsubscribe to cancel listening to prevent memory leaks

function subscribe(listener: () => void) { let isSubscribed = true ensureCanMutateNextListeners() nextListeners.push(listener) return function unsubscribe() { if (! isSubscribed) { return } if (isDispatching) { throw new Error( 'You may not unsubscribe from a store listener while the reducer is executing. ' + 'See https://redux.js.org/api/store#subscribelistener for more details.' ) } isSubscribed = false ensureCanMutateNextListeners() const index = nextListeners.indexOf(listener) nextListeners.splice(index, 1) currentListeners = null } }Copy the code

Redux.applyMiddleware

What it does: Redux middleware used to perform section operations before and after dispatch method execution

Note: The middle dispatch is store.dispatch is not enhanced by any middleware.

Core code: @redux/

const middlewareAPI: MiddlewareAPI = { getState: store.getState, dispatch: (action, ... args) => dispatch(action, ... Args)} const chain = middlewares.map(middleware => Middleware (middlewareAPI) dispatch>(... chain)(store.dispatch)Copy the code

@redux/src/compose.ts

Receives an array of func, concatenated from left to right. The reduce method of Array is used internally for rounding up.

/** * Composes single-argument functions from right to left. The rightmost * function can take multiple arguments as it provides the signature for the * resulting composite function. * * @param funcs The functions to compose. * @returns A function obtained by composing the argument functions from right * to left. For example, `compose(f, g, h)` is identical to doing * `(... args) => f(g(h(... args)))`. */ function compose(... funcs: Function[]) { if (funcs.length === 0) { // infer the argument type so it is usable in inference down the line return <T>(arg: T) => arg } if (funcs.length === 1) { return funcs[0] } return funcs.reduce( (a, b) => (... args: any) => a(b(... args)) ) }Copy the code

Inspired by the

  1. When code composition is involved in the code, consider using Componse to combine functions for subsequent extension
  2. TODO

reference

  1. Website cn.redux.js.org/introductio…
  2. Juejin. Cn/post / 684490…
  3. Coding-Guide