react-redux框架及其源碼分析

react-redux框圖

        咱們在action中所寫的dispatch之因此可以調用store.dispatch方法是由於,mapDispatchToProps方法將action中方法做爲屬性傳遞到connect中,connect將store.dispatch傳入action方法,同時connect建立了當前組件的父組件,action中方法做爲父組件屬性,當前組件使用props獲取傳入store.dispatch的action方法。javascript

技術棧:

    react-redux須要學習那些知識:java

            ES六、webpack打包工具、react、redux、UI框架、路由等react

首先重點介紹reactwebpack

react數據傳遞方式

1.內部傳遞:採用state傳遞es6

  getInitialState: function () {  
    return {  
      checked: false  
    };  
  },  
  render: function() {  
    return (  
      <ToggleButton text="Toggle me" checked={this.state.checked} />  
    );  
  }

2.父組件向子組件傳遞:採用props傳遞web

// 父組件 
<ToggleButton text="Toggle me"  />  
//子組件
render: function () {  
    var text = this.props.text;  
    return (  
        <label>{text}</label>  
    );  
  }  

3.子組件向父組件傳遞:調用子組件對象的方法傳遞redux

//子組件
var Child = React.createClass({
    render: function(){
        return (
            <div>
                請輸入郵箱:<input onChange={this.props.handleEmail}/>
            </div>
        )
    }
});
//父組件,此處經過event.target.value獲取子組件的值
var Parent = React.createClass({
    getInitialState: function(){
        return {
            email: ''
        }
    },
    handleEmail: function(event){
        this.setState({email: event.target.value});
    },
    render: function(){
        return (
            <div>
                <div>用戶郵箱:{this.state.email}</div>
                <Child name="email" handleEmail={this.handleEmail.bind(this)}/>
            </div>
        )
    }
});
React.render(
  <Parent />,
  document.getElementById('test')
);

4.跨組件傳遞:Context傳遞app

    咱們看下Provider源碼:其中(react生命週期)constructor經過props方式獲取父類的屬性store,而後getChildContext()聲明context,驗證組件信息Provider.propTypes,最後聲明瞭childrenContextTypes,使得子組件可以經過定義ContextTypes 獲取其內定義的store,若是不聲明的話,將沒法在組件中使用getChildContext()方法;框架

class Provider extends Component {
        getChildContext() {
          return { store: this.store }
        }

        constructor(props, context) {
          super(props, context)
          this.store = props.store;
        }
        render() {
          return Children.only(this.props.children)
        }
    }
    Provider.propTypes = {
        store: storeShape.isRequired,
        children: PropTypes.element.isRequired,
    }
    Provider.childContextTypes = {
        store: storeShape.isRequired,
    }

}

5.ref傳遞ide

<input ref="myInput" />
var input = this.refs.myInput;
var inputValue = input.value;

react生命週期

初始化

constructor:在裝載以前使用,初始化操做,es6語法

componentWillMount:在render以前被調用,在渲染以前作一些準備

render:返回reactElement對象,渲染頁面

componentDidMount:在render後調用,能夠獲取DOM結構,或者AJAX等請求

組件props更新

componentWillReceiveProps(nextProps):接收新的props出發,傳入新的props,和以前this.props比較,來決定是否渲染

shouldComponentUpdate:render以前使用,返回bool值,決定組件更新,若是爲FALSE,以前的操做不會觸發

componentWillUpdate:渲染以前操做,與componentWillMount相似

render:從新渲染組件

componentDidUpdate:從新渲染後調用與componentDidMount相似

組件卸載

componentWillUnmount:卸載組件和銷燬以前調用

redux組成

Action

Action 就是 View 發出的事件通知,表示 State 應該要發生變化了。 Action 是一個對象。其中的type屬性是必須的,表示 Action 的名稱。其餘屬性爲信息的載體即要傳遞的信息。

Action Creator爲一個函數,用來生成 Action的函數。

function addTodo(text) {
                     return {
                          type: ‘ADD_TODO’,
                          text
                             }
                        }

Reducer

Store 收到 Action 之後,須要給出一個新的 State,這樣 View 纔會發生變化。這種 State 的計算過程就叫作 Reducer。 Reducer 是一個函數,它接受 Action 和當前 State 做爲參數,返回一個新的 State

Store

Store 就是保存數據的地方。整個應用只能有一個 Store。Redux 提供createStore這個函數,用來生成 Store。Store主要有三個方法,

dispatch:分發action

subscribe:註冊listener,監聽state變化

getState:讀取store tree中的state

Redux經過全局惟一的store對象管理項目中的state。經過store註冊listener,註冊的listener會在store tree每次變動後執行。reducer執行後返回的新狀態會更新到store tree中,觸發由store.subscribe()註冊的全部listener。

createstore源碼 

export default function createStore(reducer, preloadedState, enhancer) {

   //這地方是說若是preloadedState是一個函數,enhancer加強沒有定義則交換
  if (typeof preloadedState === 'function' && typeof enhancer === 'undefined') {
    enhancer = preloadedState
    preloadedState = undefined
  }
//交換後enhancer定義,將(createStore)(reducer, preloadedState)做爲applyMiddleware中間件參數
  if (typeof enhancer !== 'undefined') {
    if (typeof enhancer !== 'function') {
      throw new Error('Expected the enhancer to be a function.')
    }
    return enhancer(createStore)(reducer, preloadedState)
  }
                function dispatch(action) {
                  let currentReducer = reducer
                  let currentState = preloadedState
                  try {
                    currentState = currentReducer(currentState, action)
                  } finally {
                      ...
                  }
                  const listeners = currentListeners = nextListeners
                  for (let i = 0; i < listeners.length; i++) {
                    const listener = listeners[i]
                    listener()
                  }
                  return action
                  }
                }
                function getState() {
                  return currentState
                }
                function subscribe(listener) {
                  let isSubscribed = true
                  ensureCanMutateNextListeners()
                  nextListeners.push(listener)
                  return function unsubscribe() {
                    if (!isSubscribed) {
                      return
                    }
                    isSubscribed = false
                    ensureCanMutateNextListeners()
                    const index = nextListeners.indexOf(listener)
                    nextListeners.splice(index, 1)
                  }
                }
            }

如何建立一個store:

首先建立reducer,將多個reducer合併,combineReducer其實就是建立一個大的reducers,傳入state和action,進行遍歷原先的reducer。

而後選擇須要的中間件,中間件爲了重寫dispatch,後面進行分析中間件源碼

import compose from './compose'
export default function applyMiddleware(...middlewares) {
  return (createStore) => (reducer, preloadedState, enhancer) => {
    const store = createStore(reducer, preloadedState, enhancer)
    let dispatch = store.dispatch
    let chain = []

    const middlewareAPI = {
      getState: store.getState,
      dispatch: (action) => dispatch(action)
    }
    chain = middlewares.map(middleware => middleware(middlewareAPI))
    dispatch = compose(...chain)(store.dispatch)
//返回store和重寫的dispatch
    return {
      ...store,
      dispatch
    }
  }
}
相關文章
相關標籤/搜索