期待已久的新教程上線啦!解鎖React Native開發新姿式,一網打盡React Native最新與最熱技術,點我Get!!!html
爲了幫助你們快速上手在React Native與Redux開發,在這本文中將向你們介紹如何在React Native中使用Redux?,以及一些必備基礎以及高級知識。react
本文參考了《新版React Native+Redux打造高質量上線App》課程的部分講解,更多關於React Native與Redux的實戰技巧可在《新版React Native+Redux打造高質量上線App》中查看。git
那麼如何在React Native中使用Redux?呢?github
根據須要安裝如下組件。npm
npm install --save redux
npm install --save react-redux
npm install --save-dev redux-devtools
複製代碼
react-redux
是Redux 官方提供的 React 綁定庫。 具備高效且靈活的特性。redux
<Provider>
組件: 這個組件須要包裹在整個組件樹的最外層。這個組件讓根組件的全部子孫組件可以輕鬆的使用 connect() 方法綁定 store。connect()
:這是 react-redux 提供的一個方法。若是一個組件想要響應狀態的變化,就把本身做爲參數傳給 connect() 的結果,connect() 方法會處理與 store 綁定的細節,並經過 selector 肯定該綁定 store 中哪一部分的數據。selector
:這是你本身編寫的一個函數。這個函數聲明瞭你的組件須要整個 store 中的哪一部分數據做爲本身的 props。dispatch
:每當你想要改變應用中的狀態時,你就要 dispatch 一個 action,這也是惟一改變狀態的方法。react-redux提供如下API:react-native
API原型:
<Provider store>
bash
使組件層級中的 connect() 方法都可以得到 Redux store(將store傳遞給App框架)。一般狀況下咱們須要將根組件嵌套在 標籤 中才能使用 connect() 方法。框架
class Index extends Component {
render() {
return <Provider store={configureStore()}> <AppWithNavigationState /> </Provider>
}
}
複製代碼
以上代碼片斷的完整部分能夠在課程源碼中查找。異步
在上述代碼中咱們用 標籤包裹了根組件AppWithNavigationState
,而後爲它設置了store參數,store (Redux Store)接受的是應用程序中惟一的 Redux store 對象。
API原型:
connect([mapStateToProps], [mapDispatchToProps], [mergeProps], [options])
鏈接 React 組件與 Redux store,鏈接操做會返回一個新的與 Redux store 鏈接的組件類,而且鏈接操做不會改變原來的組件類。
react-redux
提供了connect函數,connect是一個高階函數,首先傳入mapStateToProps、mapDispatchToProps,而後返回一個生產 Component 的函數(wrapWithConnect),而後再將真正的Component做爲參數傳入wrapWithConnect(MyComponent),這樣就生產出一個通過包裹的Connect組件,如:export default connect(mapStateToProps)(HomePage);
/* * 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將被更新,從而組件被更新;