美文网首页
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