揭开redux,react-redux的神秘面纱

16年开始使用react-redux,迄今也已两年多。这时候再来阅读和读懂redux/react-redux源码,虽已没有当初的新鲜感,但依然以为略有收获。把要点简单写下来,一方面供感兴趣的读者参考,另外一方面也是本身作下总结。html

为了完整阅读体验,欢迎移步到个人博客原文react

redux

react-redux最核心的内容就是redux。内带redux,react-redux只提供了几个API来关联redux与react的组件以及react state的更新。git

首先,看下如何使用redux。 redux老司机能够直接滑动滚轮至下一章。
简单来讲,redux有三个概念,action, reducer 和 dispatch。 action和dispatch比较好理解:动做指令和提交动做指令方法。而reducer,我的在字面上没有理解,但抽象层面上能够理解为用来生成state的函数。用一个简单案例体现这三个概念:github

// action
const INCREMENT = { type: 'INCREMENT' }

// reducer
function count( state = 0, action ) {
    switch( action.type ) {
        case 'INCREMENT':
            return state + 1
        default: 
          return state
    }
}

// dispatch
// 此处开始使用redux
const store = redux.createStore( count )
console.log( store.getState() )  // 0
store.dispatch( INCREMENT )
console.log( store.getState() ) // 1

接下来讲说redux中的两大模块:编程

  • store对象
  • 中间件

store对象

APIcreateStore会建立了一个store对象,建立的过程当中它主要作了下面两件事:redux

  1. 初始化state
  2. 暴露相关接口:getState(), dispatch( action ), subscribe( listener )等。其中getState()用来获取store中的实时state, dispatch(action)根据传入的action更新state, subscribe( listener)能够监听state的变化。

中间件

中间件能够用来debug或提交异步动做指令. 在初始化store的时候,咱们经过createStore( reducer, state, applyMiddleware( middleware1, middleware2 ) )添加多个中间件。
为了实现多个中间件,redux专门引入了函数式编程的compose()方法,简单来讲,compose将多层函数调用的写法变得优雅:api

// 未使用compose方法
a( b( c( 'd' ) ) )

// 用compose方法
compose( a, b, c )('d')

而中间件的写法比较奇特,是多级函数,在阅读源码的时候有点绕。显然中间件的写法还能够优化,尽管如今的写法方便在源码中使用,但对redux用户来讲稍显复杂,能够用单层函数。app

function logMiddleware({ getState  }) {
    return nextDispatch => action => {
        console.log( 'before dispatch', getState() )
        const res = nextDispatch( action )
        console.log( 'after dispatch', getState() )
        return res
    }
}

react-redux

了解了redux运做原理,就能够知道react-redux的大部分使用场景是如何运做。react-redux提供了几个API将redux与react相互关联。异步

基于上一个案例展现react-redux的用法:ide

// action
const increment = () => ({ type: 'INCREMENT' })

// reducer
function count( state = 0, action ) {
    switch( action.type ) {
        case 'INCREMENT':
            return state + 1
        default: 
          return state
    }
}

// redux
const store = Redux.createStore( count )

// react-redux
const { Provider, connect } = ReactRedux
const mapStateToProps = state => ( { count: state } )
const mapDispatchToProps = dispatch => ( { increment : () => dispatch( increment() ) } )
const App = connect( mapStateToProps, mapDispatchToProps )( class extends React.Component {
  onClick = () => {
   this.props.increment()
  }  
  render() {
        return <div>
          <p>Count: { this.props.count }</p>
          <button onClick={ this.onClick }>+</button>
        </div>
    }
} )

ReactDOM.render( <Provider store={ store }>
    <App />
</Provider>, document.getElementById( 'app' ) )

点击运行案例

react-redux提供最经常使用的两个API是:

  • Provider
  • connect

Provider

Provider本质上是一个react组件,经过react的context api(使一个组件能够跨多级组件传递props)挂载redux store中的state,而且当组件初始化后开始监听state。
当监听到state改变,Provider会从新setState在context上的storeState,简要实现代码以下:

class Provider extends Component {
    constructor(props) {
      super(props)
    
      const { store } = props
    
      this.state = {
        storeState: Redux.store.getState(),
      }
    }
    
    componentDidMount() {
      this.subscribe()
    }
    
    subscribe() {
        const { store } = this.props
        store.subscribe(() => {
          const newStoreState = store.getState()
          this.setState(providerState => {
            return { storeState: newStoreState }
          })
        })
    }
    render() {
        const Context = React.createContext(null)
        <Context.Provider value={this.state}>
            {this.props.children}
        </Context.Provider>
    }
}

connect()

connect方法经过connectHOC(HOC: react高阶组件)将部分或全部state以及提交动做指令方法赋值给react组件的props。

小结

写react不用redux就像写代码不用git, 咱们须要用redux来更好地管理react应用中的state。了解redux/react-redux的运做原理会消除咱们在使用redux开发时的未知和疑惑,而且在脑中有一个完整的代码执行回路,让开发流程变得透明,直观。

若是本文帮助到了你,我也十分荣幸, 欢迎点赞和收藏。若是有任何疑问或者建议,都欢迎在下方评论区提出。

相关文章
相关标签/搜索