返回专题

专题 2018

Redux 原理

简介 相关笔记

JavaScriptRedux原理解析面试题
本文目录2
  1. 简介
  2. Reference

简介

Redux is a predictable state container for JavaScript apps.

  • 使用中间件示例

    JavaScript
    import { createStore, applyMiddleware } from 'redux'
    import todos from './reducers'
    
    function logger({ getState }) {
      return next => action => {
        console.log('will dispatch', action)
    
        // Call the next dispatch method in the middleware chain.
        const returnValue = next(action)
    
        console.log('state after dispatch', getState())
    
        // This will likely be the action itself, unless
        // a middleware further in chain changed it.
        return returnValue
      }
    }
    
    const store = createStore(todos, ['Use Redux'], applyMiddleware(logger))
    
    store.dispatch({
      type: 'ADD_TODO',
      text: 'Understand the middleware'
    })
    // (These lines will be logged by the middleware:)
    // will dispatch: { type: 'ADD_TODO', text: 'Understand the middleware' }
    // state after dispatch: [ 'Use Redux', 'Understand the middleware' ]
    

    Reference

    🏁 Final Form - Announcement

    Two and a half years ago, about a month after Dan Abramov's unforgettable launch of Redux at React Europe 2015, I released a humble little library that managed form state in Redux, called Redux-Form, which, over the intervening period, has grown quite substantially in popularity.
    https://erikras.com/blog/final-form-announcement

    Question: How to choose between Redux's store and React's state? · Issue #1287 · reduxjs/redux

    This was referenced Nov 29, 2017 You can't perform that action at this time.
    https://github.com/reduxjs/redux/issues/1287

  • 编写一个中间件

    JavaScript
    // next 是用中间件增强之后的 dispatch
    // dispatch 是最原始的 store.dispatch
    const thunkMiddleware = ({ dispatch }) => next => action => {
      if (typeof action === 'function') {
    
        // 函数形式的 action 就把 dispatch 给这个 action,让 action 决定什么时候 dispatch (控制反转)
        return action(dispatch);
      }
    
      // 普通的 action 就直接传递给下一个中间件处理
      return next(action);
    }
    
  • createStore 原理

    JavaScript
    function dispatch(action: A) {
        if (!isPlainObject(action)) {
          throw new Error(
            `Actions must be plain objects. Instead, the actual type was: '${kindOf(
              action
            )}'. You may need to add middleware to your store setup to handle dispatching other values, such as 'redux-thunk' to handle dispatching functions. See https://redux.js.org/tutorials/fundamentals/part-4-store\#middleware and https://redux.js.org/tutorials/fundamentals/part-6-async-logic\#using-the-redux-thunk-middleware for examples.`
          )
        }
    
        if (typeof action.type === 'undefined') {
          throw new Error(
            'Actions may not have an undefined "type" property. You may have misspelled an action type string constant.'
          )
        }
    
        if (isDispatching) {
          throw new Error('Reducers may not dispatch actions.')
        }
    
        try {
          isDispatching = true
          currentState = currentReducer(currentState, action)
        } finally {
          isDispatching = false
        }
    
        const listeners = (currentListeners = nextListeners)
        for (let i = 0; i < listeners.length; i++) {
          const listener = listeners[i]
          listener()
        }
    
        return action
      }
    
  • applyMiddleware 原理> [!important]

    applyMiddleware 会把原始 dispatch 和 getState 传入 middlewares, 并且会生成最终的 dispatch

    JavaScript
    export default function applyMiddleware(...middlewares) {
      return createStore => (...args) => {
        const store = createStore(...args)
        let dispatch = () => {
          throw new Error(
            `Dispatching while constructing your middleware is not allowed. ` +
              `Other middleware would not be applied to this dispatch.`
          )
        }
    
        const middlewareAPI = {
          getState: store.getState,
          dispatch: (...args) => dispatch(...args)
        }
    		// 把原始 dispatch 和 getState 传入 middlewares
        const chain = middlewares.map(middleware => middleware(middlewareAPI))
    		// 用中间件增强之后的 dispatch, 即 next
        dispatch = compose(...chain)(store.dispatch)
    
        return {
          ...store,
          dispatch
        }
      }
    }
    

Reference

Redux 源码解析系列--中间件机制

我又回来更新了,哈哈。 这次打算做一个Redux源码解析系列(像我这么菜的,react源码研究不透,只好看看redux源码,勉强维持生活这样子)。Redux核心代码不多,主要也就三块东西: Recucer和dispatch 中间件 store enhancer(增强器,不知道这么翻译恰不恰当) 我刚开始学redux的时候就对其中间件机制很好奇,所以这次就先讲中间件啦。 .
https://zhuanlan.zhihu.com/p/50234359

Redux 进阶 -- 编写和使用中间件

本文目标:和大家探讨一下如何通过编写和使用 redex 中间件 来帮助我们更好的使用 redux 。 在上一篇文章 Redux 进阶 -- 优雅的处理 async action 中,阿大通过改善流程对接完成了水果店的升级。 但是阿大又有一个新的想法,他想详细的看看每一个顾客的购买需求来了之后,账本的前后变化。看来又要加一个新角色 记录员了。难道要像加 采购员那样手动的一个个的加吗?那可太麻烦了。正好阿大发现 redux 里有一个功能就是中间件。中间件是干嘛的呢?简而言之,就是把顾客的需求从 销售员到 收银员 之间加上各种角色来处理。每一个角色就是一个中间件。接下来阿大就开始来写中间件了。 redux 中间件写起来其实很简单,就是一个函数而已。按照它的要求。这个函数接受一个 { dispatch, getState } 对象作为参数,然后返回一个 action 。 那这样,就可以把原来的 采购员也改造成中间件了,其实采购员就是拿到了顾客需求之后让顾客的需求延迟 dispatch ,这用延迟用函数就可以做到了: 然后我们就需要把原来的顾客需求改一下了: 然后 采购员 就可以只负责采购了,改回去: 然后,我们在添加一个 记录员 的中间件: 删除掉原来的监听: - store.
https://juejin.cn/post/6844903597180715015

返回首页
上一篇React Without Concurrent Mode下一篇redux-vs-generator

Discussion

留言与讨论

想法、补充和不同意见都欢迎。