咱們在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
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;
constructor:在裝載以前使用,初始化操做,es6語法
componentWillMount:在render以前被調用,在渲染以前作一些準備
render:返回reactElement對象,渲染頁面
componentDidMount:在render後調用,能夠獲取DOM結構,或者AJAX等請求
componentWillReceiveProps(nextProps):接收新的props出發,傳入新的props,和以前this.props比較,來決定是否渲染
shouldComponentUpdate:render以前使用,返回bool值,決定組件更新,若是爲FALSE,以前的操做不會觸發
componentWillUpdate:渲染以前操做,與componentWillMount相似
render:從新渲染組件
componentDidUpdate:從新渲染後調用與componentDidMount相似
componentWillUnmount:卸載組件和銷燬以前調用
Action 就是 View 發出的事件通知,表示 State 應該要發生變化了。 Action 是一個對象。其中的type屬性是必須的,表示 Action 的名稱。其餘屬性爲信息的載體即要傳遞的信息。
Action Creator爲一個函數,用來生成 Action的函數。
function addTodo(text) { return { type: ‘ADD_TODO’, text } }
Store 收到 Action 之後,須要給出一個新的 State,這樣 View 纔會發生變化。這種 State 的計算過程就叫作 Reducer。 Reducer 是一個函數,它接受 Action 和當前 State 做爲參數,返回一個新的 State
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) } } }
首先建立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 } } }