Router
- WebApp developers should learn react-router v4 if possible
- MobApp developers could learn
- react-navigation (a.k.a ex-navigation)
- react-native-router-flux
Design principle: protect routes by connect redux store
Always protect routes if possible
// ./app/routes/AccountViewer.js
import { Scene, Router } from 'react-native-router-flux';
import Balance from '../components/Balance';
import PurchaseList from '../components/PurchaseList';
import PurchaseDetail from '../components/PurchaseDetail';
import ChooseLoginMethods from '../components/ChooseLoginMethods';
import MsisdnInputForm from '../components/MsisdnInputForm';
import IccidInputForm from '../components/IccidInputForm';
import OtpInputForm from '../components/OtpInputForm';
const AccountViewer = (props) => {
if (props.is_logined) {
return (
<Scene key='me' {...props} >
<Scene component={Balance}/>
<Scene component={PurchaseList}/>
<Scene component={PurchaseDetail}/>
</Scene>
)
}else{
return (
<Scene key='session' {...props}>
<Scene component={ChooseLoginMethods}/>
<Scene component={MsisdnInputForm}/>
<Scene component={IccidInputForm}/>
<Scene component={OtpInputForm}/>
</Scene>
)
}
}
const mapStateToProps = (state, ownProps) => {
is_logined: is_logined(state)
}
export default connect({mapStateToProps})(AccountViewer)
// ./app/index.js
import AccountViewer from './routes/AccountViewer';
import { Scene, Router } from 'react-native-router-flux';
import { tracker } from './service';
const RootRouter = (props) => (
<Router {...props} tracker={tracker} >
<Scene key="root">
<Scene key="ExploreTab" title="Explore" icon={Tabbar}>
<Scene key="Explore" component={Explore} title="" navBar={NavbarWithAppIcon} rightIcon={top_search} onRight={() => Actions.Ex_Search()} />
</Scene>
<AccountViewer title="MyAccount" icon={Tabbar} />
</Scene>
</Router>
)
export default connect()(RootRouter)
// ./app/App.js
import RootRouter from './index.js'
import i18n from './i18n';
import store from './store';
const App = () => (
<I18nextProvider i18n={ i18n }>
<Provider store={store}>
<RootRouter onExitApp={RNExitApp.exitApp}/>
<NotificationContainer/>
</Provider>
</I18nextProvider>
)
export default App;
Design principle: Prepare a routerSaga to intercept navigation
Create a routerSaga if we are going to listen to page change
Some router has limitation to intercept navigation change event, say
- tab change in react-native-router-flux
To implement optimistic update flow, we can create routerSaga and listen to specific action
// ./app/sagas/routerSaga.js
function* rootSaga () {
while (true){
const action = yield take([ActionsConst.JUMP, ActionsConst.PUSH]);
switch (action.key){
case "myaccount":
const is_logined = Yield select(is_logined)
if (is_logined) yield put (SHOW_BALANCE)
break;
}
}
}
// ./app/sagas/AccountViewer.js
function* watchShowBalance(){
while (true){
yield take(SHOW_BALANCE);
yield call(api)
yield put(BALANCE_READY, response);
}
}