16年開始使用react-redux,迄今也已兩年多。這時候再來閱讀和讀懂redux/react-redux源碼,雖已沒有當初的新鮮感,但依然以爲略有收穫。把要點簡單寫下來,一方面供感興趣的讀者參考,另外一方面也是本身作下總結。html
爲了完整閱讀體驗,歡迎移步到個人博客原文。react
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
對象APIcreateStore
會建立了一個store
對象,建立的過程當中它主要作了下面兩件事:redux
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 } }
瞭解了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開發時的未知和疑惑,而且在腦中有一個完整的代碼執行迴路,讓開發流程變得透明,直觀。
若是本文幫助到了你,我也十分榮幸, 歡迎點贊和收藏。若是有任何疑問或者建議,都歡迎在下方評論區提出。