美文网首页
React Native集成 react-navigation和

React Native集成 react-navigation和

作者: 楼上那只猫 | 来源:发表于2019-05-22 17:10 被阅读0次
    1. 初始化项目,这里我使用的是 0.59.5 版本
    react-native init myProject --version 0.59.5
    

    2.安装 react-navigation 和 react-redux

    yarn add react-navigation
    react-redux
    
    1. 构建导航,最终呈现结果如下


      image.png

    下面的代码在项目的 App.js文件中编写

    /**
     * Sample React Native App
     * https://github.com/facebook/react-native
     *
     * @format
     * @flow
     */
    
    import {
      createBottomTabNavigator,
      createAppContainer,
      createStackNavigator,
      createSwitchNavigator
    } from 'react-navigation';
    import Home from "./app/page/home";
    import Setting from "./app/page/setting";
    import Detail from "./app/page/detail";
    import {AuthSwitch} from "./app/navigation/authNavigation";
    import {createStore} from "redux";
    import {counter} from "./app/redux/reducer";
    import React, {Component} from 'react';
    import {Provider} from "react-redux";
    import {View} from 'react-native';
    
    
    
    const tabNavigator = createBottomTabNavigator({
      Home:{
        //每个 tab 都是一个 stack,目的是可以单独控制 header
        screen:createStackNavigator({
          Home:{
            screen:Home,
            navigationOptions:{
              header:null,
            }
          }
        }),
        navigationOptions:() => ({
          tabBarLabel:'Home',
        })
      },
      Setting:{
        screen:createStackNavigator({
          Setting:{
            screen:Setting,
            navigationOptions:{
              header:null,
            }
          }
        }),
        navigationOptions:() => ({
          tabBarLabel:'Setting',
        })
      },
    }, {
      initialRouteName:'Home',
      swipeEnabled: false,
      animationEnabled: false,
      backBehavior:'none',
      tabBarOptions: {
        inactiveTintColor: '#808080',
        activeTintColor: '#e9ab62',
        labelStyle: {
          fontSize: 12,
          paddingTop: 3,
          paddingBottom: 2
        },
        style: {
          paddingTop: 4
        }
      }
    });
    
    const MainNavigator = createStackNavigator({
      //tab 放在 stack 中,可以保证 navigate 到二级页面时隐藏底部 tabbar
      Tab: {
        screen: tabNavigator,
        navigationOptions: {
          header: null
        }
      },
      Detail:{
        screen: Detail,
        navigationOptions: {
          title: '详情',
        }
      }
    }, {
      headerMode: 'screen',
      defaultNavigationOptions: {
        headerBackTitle: null,
        headerTitleStyle: {
          color: 'white',
        },
        headerBackTitleStyle: {
          color: 'white'
        },
        headerStyle: {
          backgroundColor: '#37426A',
          headerTransparent: true,
          borderBottomWidth: 0,
          borderBottomColor: 'transparent',
        },
        headerTintColor: 'white',
        gesturesEnabled: true,
      }
    });
    
    const RootStack = createStackNavigator({
      Main:{
        screen:MainNavigator,
      },
      AuthModal:{
        screen:AuthSwitch,
      }
    }, {
      mode: 'modal',
      headerMode: 'none',
    });
    
    export const AppNavigator = createSwitchNavigator({
      App: {
        screen:RootStack,
      },
    });
    
    const RootNavigator = createAppContainer(AppNavigator);
    //创建 store
    const store = createStore(counter);
    export default class App extends Component {
      render(){
        return(
            <Provider store={store}>
              <View style={{ flex:1 }}>
                <RootNavigator/>
              </View>
            </Provider>
        )
      }
    
    }
    
    1. 导航中用到的 auth 模块
    
    import {createStackNavigator, createSwitchNavigator} from "react-navigation";
    import Login from "../page/login";
    import Password from "../page/password";
    
    
    export const BACKGROUND_STACK_CONFIG_PARENT = {
        headerStyle:{ // 清除parent Header的底部线条
            backgroundColor:'transparent',
            borderBottomWidth:0,
            shadowOpacity: 0, // android
            elevation: 0 // android
        },
        headerTitleStyle:{
            color:'white'
        },
        headerTransparent:true
    };
    
    //登录验证的 stack
    const AuthNavigator = createStackNavigator({
        Login:{
            screen:Login,
            navigationOptions:{
                BACKGROUND_STACK_CONFIG_PARENT,
                title:'Login',
            }
        },
        Password:{
            screen:Password,
            navigationOptions:{
                BACKGROUND_STACK_CONFIG_PARENT,
                title:'Password',
            }
        }
    });
    //以AuthNavigator为基础构建 switch navigator
    export const AuthSwitch = createSwitchNavigator({
        AuthLogin:{
            screen:AuthNavigator,
        },
    });
    

    接下来,需要编写 action 和 reducer

    1. action 的编写
      action就是一个 JavaScript 对象
    //aciton.js
    
    export const add = {
        type:'ADD',
    };
    export const decrease = {
        type:'DECREASE',
    };
    
    1. reducer 的编写
      reducer 是一个纯函数,输入一样的话,输出必定一样
    //reducer.js
    
    export function counter(state = {count:0}, action) {
        let count = state.count;
        switch (action.type) {
            case 'ADD': {
                return {
                    count: count + 1,
                }
            }
            case 'DECREASE':{
                return {
                    count: count - 1,
                }
            }
            default:
                return state;
        }
    }
    
    1. 在 home 页,用 connect 把组件包装为容器组件,从而能够获取全局的 state 和 dispatch 作为页面的 props
    //home.js
    
    import React, {PureComponent} from 'react';
    import { Text, View } from 'react-native';
    import {add, decrease} from "../redux/action";
    import {connect} from "react-redux";
    
    function mapStateToProps(state) {
        return {
            count:state.count
        };
    }
    function mapDispatchToProps(dispatch) {
        return{
            addCount:() => dispatch(add),
            decreaseCount:() => dispatch(decrease),
        }
    }
    @connect(mapStateToProps, mapDispatchToProps)
    class Home extends PureComponent {
    
        constructor(props) {
            super(props);
            this.state = {
                count:0
            }
        }
    
        render() {
            let {count, addCount, decreaseCount} = this.props;
            return (
                <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
                    <Text style={{fontSize:26}} onPress={() => this.props.navigation.navigate('Detail')}>Home!</Text>
                    <Text style={{fontSize:26, color:'red'}} onPress={() => addCount()}>ADD</Text>
                    <Text style={{fontSize:26, color:'red'}}>{count}</Text>
                    <Text style={{fontSize:26, color:'#459AFF'}} onPress={() => decreaseCount()}>DECREASE</Text>
                </View>
            );
        }
    }
    
    export default Home;
    

    至此,主要工作已经完成。

    下面是剩下的几个页面

    //detail.js
    
    
    import React, {Component} from 'react';
    import { Text, View } from 'react-native';
    
    
    class Detail extends Component {
        render() {
            return (
                <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
                    <Text style={{fontSize:26}} onPress={() => this.props.navigation.navigate('Login')}>Detail!</Text>
                </View>
            );
        }
    }
    
    export default Detail;
    
    //login.js
    
    
    import React, {Component} from 'react';
    import { Text, View } from 'react-native';
    
    
    class Login extends Component {
        render() {
            return (
                <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor:'#FFBE9E' }}>
                    <Text style={{fontSize:26}} onPress={() => this.props.navigation.navigate('Password')}>Login!</Text>
                </View>
            );
        }
    }
    
    export default Login;
    
    //password.js
    
    
    import React, {Component} from 'react';
    import { Text, View } from 'react-native';
    
    
    class Password extends Component {
        render() {
            return (
                <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
                    <Text style={{fontSize:26}} onPress={() => this.props.navigation.navigate('Home')}>Password!</Text>
                </View>
            );
        }
    }
    
    export default Password;
    
    //setting.js
    
    
    import React, {Component} from 'react';
    import { Text, View } from 'react-native';
    
    
    class Setting extends Component {
        render() {
            return (
                <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor:'#B7DEFF' }}>
                    <Text style={{fontSize:26}}>Setting</Text>
                    <Text style={{fontSize:26}}>Setting!</Text>
                </View>
            );
        }
    }
    
    export default Setting;
    

    最后需要注意的是,为了支持装饰器语法,需要额外安装几个三方库

    yarn add babel-plugin-transform-decorators-regacy
    yarn add @babel/plugin-transform-runtime
    yarn add react-native-typescript-transformer
    

    安装完成后,在项目中新建一个 .babelrc配置文件,然后输入以下内容

    {
      "presets": ["module:metro-react-native-babel-preset"],
      "plugins":[
        ["@babel/plugin-proposal-decorators", { "legacy": true }]
      ]
    }
    

    P.S.如果安装的是 react-redux 7.0以上版本,那么下面的语句会导致在 debug 模式下不能运行,目前还没找到解决办法,我暂时在 release 下运行的。
    具体可参考:https://github.com/facebook/react-native/issues/24458

    @connect(mapStateToProps, mapDispatchToProps)
    

    参考文档:
    https://reactnavigation.org/en/
    http://cn.redux.js.org

    demo 地址:
    https://github.com/mike1023/react-native-react-redux

    相关文章

      网友评论

          本文标题:React Native集成 react-navigation和

          本文链接:https://www.haomeiwen.com/subject/yqduzqtx.html