少停
>
dva和react-navigation的结合使用
今天,学习下RN中的另外一个全家桶套餐架构:dva+React-Navigation, 本文基于react-native
:0.55.4
,dva-core
:^1.3.0
,react-navigation
:^2.5.1
,react-navigation-redux-helpers
:^2.0.4
,react-redux
:0^5.0.7
所撸.
react-native的官方dva-demo dva官方github 废话不多缩,首先,新建一个项目,添加一堆相应库:npm install mobx dva-core --save
引入dvanpm install mobx react-navigation-redux-helpers --save
引入react-navigation-redux-helpersnpm install mobx react-redux --save
引入react-reduxnpm install babel-plugin-transform-decorators-legacy babel-preset-react-native-stage-0 --save-dev
能够使用@标签npm install react-navigation --save
引入导航库 然后修改一下工程里面的.babelrc:
1 2 3 4 5 { "presets": ["react-native"], "plugins": ["transform-decorators-legacy"] }
OK,基本的架子已经搭好. 然后新建一个src目录.这里存放基本代码和基本图片之类的.
然后,在入口文件index.js
中,修改一下代码:
1 2 3 4 5 6 7 8 import './App'; console.ignoredYellowBox = [ 'Warning: componentWillMount is deprecated', 'Warning: componentWillReceiveProps is deprecated', 'Warning: componentWillUpdate is deprecated', 'Warning: isMounted(...) is deprecated', ]
在App.js
中基础代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 import React from 'react' import { AppRegistry } from 'react-native' import dva from './src/Utils/dva' import Router, { routerMiddleware, routerReducer } from './router' import appModel from './src/models/app' const app = dva({ initialState: {}, models: [appModel], extraReducers: { router: routerReducer }, onAction: [routerMiddleware], onError(e) { console.log('onError', e) }, }) const App = app.start(<Router />) AppRegistry.registerComponent('rn_dva', () => App)
ok,如上图所示,dva的代码相比redux来说少了很多,不在需要大量的赋值粘贴,基本的逻辑代码均可以放在models中,其中的Utils只是dva的一个工具组,其中的代码并不多.一如既往,对着IDE就是一堆疯狂输出.完成的功能和之前的redux和Mobx一样.models
下的app.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 import { createAction, NavigationActions } from '../Utils' export default { namespace: 'app', state: { num: 0, mineType: '红', }, reducers: { updateState(state, { payload }) { return { ...state, ...payload } }, }, effects: { *add({ payload }, { call, put }) { yield put(createAction('updateState')({ num:payload ,mineType:'红'})) }, *sub({ payload }, { call, put }) { yield put(createAction('updateState')({ num:payload ,mineType:'蓝' })) } }, subscriptions: { }, }
Utils
下的dva.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 import React from 'react' import { create } from 'dva-core' import { Provider, connect } from 'react-redux' export { connect } export default function(options) { const app = create(options) // HMR workaround if (!global.registered) options.models.forEach(model => app.model(model)) global.registered = true app.start() // eslint-disable-next-line no-underscore-dangle const store = app._store app.start = container => () => <Provider store={store}>{container}</Provider> app.getStore = () => store return app }
Utils
下的index.js
1 2 3 4 export { NavigationActions, StackActions } from 'react-navigation' export const createAction = type => payload => ({ type, payload })
剩下的就是两个UI界面了:One.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 /** * Sample React Native App * https://github.com/facebook/react-native * @flow */ import React, { Component } from 'react'; import { Platform, StyleSheet, Text, View, Image } from 'react-native'; import { connect } from 'react-redux' import { createAction, NavigationActions } from '../Utils' import {Images} from "../Image"; const instructions = Platform.select({ ios: 'Press Cmd+R to reload,\n' + 'Cmd+D or shake for dev menu', android: 'Double tap R on your keyboard to reload,\n' + 'Shake or press menu button for dev menu', }); type Props = {}; @connect(({ app }) => ({ ...app })) export default class One extends Component<Props> { static navigationOptions = { tabBarLabel: '苹果', tabBarIcon: ({ focused, tintColor }) => ( <Image source={focused ? Images.Tab.OneActive : Images.Tab.One} style={{ width: 25, height: 25 }} /> ), } render() { return ( <View style={styles.container}> <Text onPress={()=>this.add()}> + 红 </Text> <Text> One {this.props.num} </Text> <Text onPress={()=>this.sub()}> - 蓝 </Text> </View> ); } add =() =>{ this.props.dispatch(createAction('app/add')(this.props.num + 1)) } sub =() =>{ this.props.dispatch(createAction('app/sub')(this.props.num - 1)) } componentDidMount() { console.log(this.props) } } const styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor: '#F5FCFF', }, welcome: { fontSize: 20, textAlign: 'center', margin: 10, }, instructions: { textAlign: 'center', color: '#333333', marginBottom: 5, }, });
Two.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 /** * Sample React Native App * https://github.com/facebook/react-native * @flow */ import React, { Component } from 'react'; import { Platform, StyleSheet, Text, View, Image } from 'react-native'; import { connect } from 'react-redux' import { createAction, NavigationActions } from '../Utils' import {Images} from "../Image"; const instructions = Platform.select({ ios: 'Press Cmd+R to reload,\n' + 'Cmd+D or shake for dev menu', android: 'Double tap R on your keyboard to reload,\n' + 'Shake or press menu button for dev menu', }); type Props = {}; @connect(({ app }) => ({ ...app })) export default class Two extends Component<Props> { static navigationOptions = { tabBarLabel: '安卓', tabBarIcon: ({ focused, tintColor }) => ( <Image source={focused ? Images.Tab.TwoActive : Images.Tab.Two} style={{ width: 25, height: 25 }} /> ), } render() { return ( <View style={[styles.container,{backgroundColor:this.props.mineType == '红' ? 'red' : 'blue'}]}> <Text style={styles.welcome}> TWO + {this.props.mineType} </Text> </View> ); } componentDidMount() { console.log(this.props.mineType) } } const styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor: '#F5FCFF', }, welcome: { fontSize: 20, textAlign: 'center', margin: 10, }, instructions: { textAlign: 'center', color: '#333333', marginBottom: 5, }, });
OK,以上就是全部代码. 效果图:
源码地址
另外:redux+react-navigation 另外:Mbox+react-navigation