Practice
以下的code大部份來自 Mastering React Native(書)
creating the store
為了從reducer創建store,我們使用redux內的 createStore (這是一個function,傳入reducer,返回object。有提供幾個方法跟store交互)
跟store交互的方法
dispatch(action) - 直接向store 發出一個action
getState() - 獲取現在app內的整個store state
subscribe(for web) - 訂閱store的更新,可參考此sample
redux 為 single store,此 createStore 方法在應用內應該只會被呼叫過一次
只有一個reducer的時候
import { createStore } from 'redux';
const initialState = {
count: 0
};
const countReducer = (state = initialState, action) => {
switch (action.type) {
case 'INCREMENT':
return {
count: state.count + 1
};
case 'DECREMENT':
return {
count: state.count - 1
};
case 'ZERO':
return {
count: 0
};
default:
return state;
}
}
export default createStore(countReducer);
多個reducer
import { combineReducers, createStore } from 'redux';
//count Reducer
import count from 'reducers/count';
//metadata Reducer
import metadata from 'reducers/metadata';
const reducer = combineReducers({
count,
metadata
});
export default createStore(reducer);
使用combineReducers function,將多個小reducer創建成一個大的reducer模塊化reducers。每個reducer的名字都對應到(store)state objec裡該reducer正在管理的key 如上,count由count reducer管理,metadata由metadata reducer管理。
入口
要使用 redux 的component(通常就是整個app的入口)app.js from here
import React, {Component} from 'react';
import { createStore, applyMiddleware, combineReducers } from 'redux';
import { Provider } from 'react-redux';
import thunk from 'redux-thunk';
import * as reducers from '../reducers';
import CounterApp from './counterApp';
const createStoreWithMiddleware = applyMiddleware(thunk)(createStore);
const reducer = combineReducers(reducers);
const store = createStoreWithMiddleware(reducer);
export default class App extends Component {
render() {
return (
<Provider store={store}>
<CounterApp />
</Provider>
);
}
}
Action creators
The component that creates the action will directly dispatch the action to the store
action.js
通常會把INCREMENT和DECREMENT這些type參數用統一寫在另一頁.js內並且宣告為const(因為action & reducer都會需要用到)
const INCREMENT = 'INCREMENT';
const DECREMENT = 'DECREMENT’;
export function increment() {
return {
type: types.INCREMENT
};
}
export function decrement() {
return {
type: types.DECREMENT
};
}
要使用action的component => index.js
ps.在此 Counter為自定義的component。 store 為 export store的.js
import React, {Component} from 'react'
import Counter from '../components/counter'
import { increment, decrement } from './src/actions'
import store from './src/store'
export default class CounterApp extends Component {
render() {
return (
<Counter
value={store.getState()}
onIncrement={() => store.dispatch(increment())}
onDecrement={() => store.dispatch(decrement())}
/>
);
}
}
React context and providers
在react內父組件(parent component)可以將參數傳遞給子組件(children),也就是props,這被稱作為context。 如果某個元件(element)向該子元件提供了context,無論子元件在樹結構內(tree)多底,都能訪問該參數。 Provider 就是使用此來創建。 通過Provider組建將整個Redux state tree公開給App。 Provider包了整個應用(app),並且context to任何其他在此app內有在監聽的React組件。 react-redux 使用這種模式提供作為context的store給任何需要訪問store的component(此app內的component)。 所以要使用Provider,需要先從react-redux中import,並且給Provider store這個參數。
import React, { Component } from 'react'
import {
AppRegistry,
StyleSheet,
Text,
View,
} from 'react-native'
import { Provider } from 'react-redux'
import store from './src/store'
class Counter extends Component {
render() {
return (
<Provider store={store}>
...
</Provider>
);
}
}
AppRegistry.registerComponent('Counter', () => Counter)
Middleware
為了適應異步(asynchronous)操作和其他自定義的操作,Redux提供了middleware結構。 ps.所謂的異步操作,ex.跟server要資料,call Api…等等 In Redux, middleware is injected between the dispatching of an action and its arrival at the reducer. 我們需要將 middleware 透過 applyMiddleware 加進store內。applyMiddleware為 redux 內的一個function 以下為sample code,加入 redux-logger 和 redux-thunk(記得要先install(yarn) redux-logger 和 redux-thunk)
import { createStore, combineReducers, applyMiddleware} from 'redux'
import { createLogger } from 'redux-logger'
import thunk from 'redux-thunk'
import reducers from './reducers'
const logger = createLogger()
const createStoreWithMiddleware = applyMiddleware(logger, thunk)(createStore)
const store = createStoreWithMiddleware(combineReducers(reducers))
export default store
參考
Last updated