Redux&Redux-Thunk源码分析题纲

Redux&Redux-Thunk源码分析

响应式编程

  • React/ReactNative
  • Flutter
  • SwiftUI
  • 小程序
  • Vue.js?

类似于信号传递,改变数据能直接驱动绑定该数据的UI渲染。不需要命令式编程那样显式的发送setText(text)等指令。

存在问题

将整个应用看作是一个状态机,State树直接决定了UI的样式。

  • 如何在不同UI节点之间共享数据是最大的问题
  • 学习Redux的必要性,所有响应式框架基本都有类似的库

Redux管理应用的状态。

  • Redux简洁优雅,精品

Redux图例

image

es6的预备知识

  • 箭头函数(闭包)
// es5
var fn = function(a, b) {
    return a + b;
}

// es6 箭头函数写法,当函数直接被return时,可以省略函数体的括号
const fn = (a, b) => a + b;
  • 展开运算符
const arr1 = [1, 2, 3];
// 这样,arr2 就变成了[1, 2, 3, 10, 20, 30];
const arr2 = [...arr1, 10, 20, 30];
  • 对象字面量
const name = 'Jane';
const age = 20

// es5
var person = {
    name: name,
    age: age
};

// es6
const person = {
    name,
    age
}
  • 对象的解构访问
const people = {
    name: 'lux',
    age: 20
}

const { name, age } = people
  • Object.keys()
let person = {
    name: "linux",
    age: 20
};
// ["name", "age"]
Object.keys(person); 
  • Array.reduce()

Redux中的名词

  • store, createStore(reducer,preState,enhancer)
  • state
  • action
  • store.dispatch(action)
  • reducer(preState, action)
  • middleware

Redux源码目录

  • redux-master/src
├── applyMiddleware.js  # 用于引入异步,日志等中间件
├── bindActionCreators.js # 返回可以创建action的函数
├── combineReducers.js # 分散的reducer集合为一个
├── compose.js # compose(f,g,h)等价于 f(g(h(...args))))
├── createStore.js # 创建一个store
├── index.js # redux对外导出的API
└── utils # 工具类暂时忽略
    ├── actionTypes.js
    ├── isPlainObject.js
    └── warning.js

Redux代码片段

js的表达能力,所见即所得。阅读流畅,不被各种静态语言附加的关键字干扰。但是代码量规模扩大,可能会难以维护。

  • createStore.js
export default function createStore(reducer, preloadedState, enhancer) {
    ...
    
    // createStore(reducer,enhancer);
    if (typeof preloadedState === 'function' && typeof enhancer === 'undefined') {
        enhancer = preloadedState
        preloadedState = undefined
    }

    if (typeof enhancer !== 'undefined') {
        if (typeof enhancer !== 'function') {
            throw new Error('Expected the enhancer to be a function.')
        }

        // 中间件. enhancer(createStore)返回函数, function(reducer, preloadedState) -> Store
        return enhancer(createStore)(reducer, preloadedState)
    }
    
    ...
    
    // 函数内的局部变量被捕获
    let currentReducer = reducer
    let currentState = preloadedState
    let currentListeners = []
    let nextListeners = currentListeners
    let isDispatching = false
  
    ...
    
    function getState() { ... }
    function subscribe(listener) { ... }
    function dispatch(action) { ... }
    
    ...
    
    return {
        dispatch,
        subscribe,
        getState
    }
}
  • combineReducers.js
  • compose.js
  • applyMiddleware.js

Redux-Thunk

  • 解决异步问题
  • Redux-Thunk 50-lines 12.5k-stars
  • 函数式
    • 函数可以作为参数和返回值
    • 函数可以捕获外部变量:参数、局部值
    • 知道是什么和知道如何做之间存在着巨大的鸿沟

参考