根據須要安裝如下組件。html
npm install --save redux npm install --save react-redux npm install --save-dev redux-devtools
react-redux
是Redux 官方提供的 React 綁定庫。 具備高效且靈活的特性。react
<Provider>
組件: 這個組件須要包裹在整個組件樹的最外層。這個組件讓根組件的全部子孫組件可以輕鬆的使用 connect() 方法綁定 store。connect()
:這是 react-redux 提供的一個方法。若是一個組件想要響應狀態的變化,就把本身做爲參數傳給 connect() 的結果,connect() 方法會處理與 store 綁定的細節,並經過 selector 肯定該綁定 store 中哪一部分的數據。selector
:這是你本身編寫的一個函數。這個函數聲明瞭你的組件須要整個 store 中的哪一部分數據做爲本身的 props。dispatch
:每當你想要改變應用中的狀態時,你就要 dispatch 一個 action,這也是惟一改變狀態的方法。react-redux提供如下API:git
API原型:
<Provider store>
github
使組件層級中的 connect() 方法都可以得到 Redux store(將store傳遞給App框架)。一般狀況下咱們須要將根組件嵌套在 標籤 中才能使用 connect() 方法。npm
class Index extends Component { render() { return <Provider store={configureStore()}> <AppWithNavigationState /> </Provider> } }
以上代碼片斷的完整部分能夠在課程源碼中查找。redux
在上述代碼中咱們用 標籤包裹了根組件AppWithNavigationState
,而後爲它設置了store參數,store (Redux Store)接受的是應用程序中惟一的 Redux store 對象。框架
API原型:
connect([mapStateToProps], [mapDispatchToProps], [mergeProps], [options])
異步
鏈接 React 組件與 Redux store,鏈接操做會返回一個新的與 Redux store 鏈接的組件類,而且鏈接操做不會改變原來的組件類。ide
react-redux`提供了connect函數,connect是一個高階函數,首先傳入mapStateToProps、mapDispatchToProps,而後返回一個生產 Component 的函數(wrapWithConnect),而後再將真正的Component做爲參數傳入wrapWithConnect(MyComponent),這樣就生產出一個通過包裹的Connect組件,如:`export default connect(mapStateToProps)(HomePage);
建立action函數
/* * action 類型 */ export const ADD_TODO = 'ADD_TODO'; export const COMPLETE_TODO = 'COMPLETE_TODO'; export const SET_VISIBILITY_FILTER = 'SET_VISIBILITY_FILTER' /* * 其它的常量 */ export const VisibilityFilters = { SHOW_ALL: 'SHOW_ALL', SHOW_COMPLETED: 'SHOW_COMPLETED', SHOW_ACTIVE: 'SHOW_ACTIVE' }; /* * action 建立函數 */ export function addTodo(text) { return { type: ADD_TODO, text } } export function completeTodo(index) { return { type: COMPLETE_TODO, index } } export function setVisibilityFilter(filter) { return { type: SET_VISIBILITY_FILTER, filter } }
以上代碼片斷的完整部分能夠在課程源碼中查找。
import { combineReducers } from 'redux' import { ADD_TODO, COMPLETE_TODO, SET_VISIBILITY_FILTER, VisibilityFilters } from './actions' const { SHOW_ALL } = VisibilityFilters function visibilityFilter(state = SHOW_ALL, action) { switch (action.type) { case SET_VISIBILITY_FILTER: return action.filter default: return state } } function todos(state = [], action) { switch (action.type) { case ADD_TODO: return [ ...state, { text: action.text, completed: false } ] case COMPLETE_TODO: return [ ...state.slice(0, action.index), Object.assign({}, state[action.index], { completed: true }), ...state.slice(action.index + 1) ] default: return state } } //經過combineReducers將多個reducer合併成一個rootReducer const todoApp = combineReducers({ visibilityFilter, todos }) export default todoApp
以上代碼片斷的完整部分能夠在課程源碼中查找。
這裏經過Redux提供的combineReducers
方法,將多個reducer聚合成一個rootReducer。
import {createStore} from 'redux' import todoApp from './reducers' let store = createStore(todoApp)
這裏經過Redux提供的createStore
方法,建立了store;
使用<Provider>
包裹根組件
import {Provider} from 'react-redux' export default class index extends Component { render() { return (<Provider store={store}> <App/> </Provider>) } }
以上代碼片斷的完整部分能夠在課程源碼中查找。
這裏咱們使用react-redux
提供的<Provider>
來包裹咱們的根組件,讓根組件的因此子組件都能使用 connect() 方法綁定 store。
function selectTodos(todos, filter) { switch (filter) { case VisibilityFilters.SHOW_ALL: return todos case VisibilityFilters.SHOW_COMPLETED: return todos.filter(todo => todo.completed) case VisibilityFilters.SHOW_ACTIVE: return todos.filter(todo => !todo.completed) } } // Which props do we want to inject, given the global state? // Note: use https://github.com/faassen/reselect for better performance. function select(state) { return { visibleTodos: selectTodos(state.todos, state.visibilityFilter), visibilityFilter: state.visibilityFilter } } // 包裝 component ,注入 dispatch 和 state 到其默認的 connect(select)(App) 中; export default connect(select)(App)
以上代碼片斷的完整部分能夠在課程源碼中查找。
經過上述代碼咱們聲明App
組件須要整個 store 中的哪一部分數據做爲本身的 props,這裏用到了connect
,咱們將select
做爲參數傳給connect
,connect
會返回一個生成組件函數,而後咱們將App組件當作參數傳給這個函數。
connect是一個高階函數,首先傳入mapStateToProps、mapDispatchToProps,而後返回一個生產 Component 的函數(wrapWithConnect),而後再將真正的Component做爲參數傳入wrapWithConnect(MyComponent),這樣就生產出一個通過包裹的Connect組件
render() { // Injected by connect() call: const {dispatch, visibleTodos, visibilityFilter} = this.props return ( <View> <AddTodo onAddClick={text => dispatch(addTodo(text)) } toast={this.toast} /> <TabBar filter={visibilityFilter} onFilterChange={nextFilter => dispatch(setVisibilityFilter(nextFilter)) }/> <TodoList todos={visibleTodos} onTodoClick={index => dispatch(completeTodo(index)) } toast={this._toast()} /> <Toast ref={toast => this.toast = toast}/> </View> ) }
以上代碼片斷的完整部分能夠在課程源碼中查找。
在這裏咱們經過dispatch
將action發送到store,store會將這個action
分發給reducer
,reducer
會建立當前state的副本,而後修改該副本並返回一個新的state,這樣一來store樹將被更新,而後對應組件的props將被更新,從而組件被更新;