美文网首页web前端开发
React Navigation5.X (Stack,Botto

React Navigation5.X (Stack,Botto

作者: 会飞的鱼儿_0012 | 来源:发表于2020-03-18 18:03 被阅读0次

    React Navigation V5 的发布和之前版本写法上有些不同,这篇文章就讲Stack,BottomTab,Drawer使用和登录权限认证

    v5移除了createSwitchNavigator登录权限认证会和之前有些变动

    在新版React Navigation V5中使用的新的HOC模式,只需要在应用最外层包裹 NavigationContainer

    import React from 'React'
    import { NavigationContainer } from '@react-navigation/native';
    
    export default function App() {
      return (
        <NavigationContainer>{/* Rest of your app code */}</NavigationContainer>
      );
    }
    

    文章涉及代码:github

    开始使用React Navigation V5

    createStackNavigator

    · StackNavigator现在的写法类似数据结构的堆栈
    默认情况下屏幕的跳转方式 ios 从右侧滑入,android 从底部划入,可以在ScreenOptions中设置屏幕的跳转方式 cardStyleInterpolator文档

      screenOptions={{
          cardStyleInterpolator: CardStyleInterpolators.forHorizontalIOS,
      }}>
    
    import React from 'react';
    
    import {NavigationContainer} from '@react-navigation/native';
    import {createStackNavigator} from '@react-navigation/stack';
    import {HomeScreen, DetailsScreen} from './Screen';
    
    const Stack = createStackNavigator();
    
    function StackScreen() {
      return (
        <Stack.Navigator 
          screenOptions={{
            cardStyleInterpolator: CardStyleInterpolators.forHorizontalIOS,
          }}>
          <Stack.Screen name="Home" component={HomeScreen} />
          <Stack.Screen name="Details" component={DetailsScreen} />
        </Stack.Navigator>
      );
    }
    
    export default function App() {
      return (
        <NavigationContainer>
          <StackScreen />
        </NavigationContainer>
      );
    }
    

    createDrawerNavigator

    93rpr-zkv73.gif

    点击按钮或从屏幕侧边划入显示抽屉界面

    import React from 'react';
    import {NavigationContainer} from '@react-navigation/native';
    import {createDrawerNavigator} from '@react-navigation/drawer';
    
    const Drawer = createDrawerNavigator();
    function DrawerScreen() {
      return (
        <Drawer.Navigator>
          <Drawer.Screen name="Home" component={HomeScreen} />
          <Drawer.Screen name="Setting" component={SettingScreen} />
        </Drawer.Navigator>
      );
    }
    
    export default function App() {
      return (
        <NavigationContainer>
          <DrawerScreen/>
        </NavigationContainer>
      );
    }
    

    createBottomTabNavigator


    屏幕底部TabBar

    import React from 'react';
    import {View} from 'react-native';
    import {NavigationContainer} from '@react-navigation/native';
    import {createBottomTabNavigator} from '@react-navigation/bottom-tabs';
    const Tab = createBottomTabNavigator();
    const TabBarIcon = (focused, color) => {
      return (
        <View
          style={{
            width: focused ? 24 : 18,
            height: focused ? 24 : 18,
            backgroundColor: color,
          }}
        />
      );
    };
    function TabScreen() {
      return (
        <Tab.Navigator
          tabBarOptions={{activeTintColor: '#FD7328', inactiveTintColor: '#999'}}
          screenOptions={{
            tabBarIcon: ({focused, color}) => {
              return TabBarIcon(focused, color);
            },
          }}>
          <Tab.Screen
            name="Home"
            component={HomeScreen}
            options={{title: '首页'}}
          />
          <Tab.Screen
            name="Mine"
            component={MineScreen}
            options={{title: '我的'}}
          />
        </Tab.Navigator>
      );
    }
    
    export default function App() {
      return (
        <NavigationContainer>
          <TabScreen />
        </NavigationContainer>
      );
    }
    

    Stack,Drawer,BottomTab结合使用

    import React from 'react';
    import {View} from 'react-native';
    import {NavigationContainer} from '@react-navigation/native';
    import {
      createStackNavigator,
      CardStyleInterpolators,
    } from '@react-navigation/stack';
    import {createDrawerNavigator} from '@react-navigation/drawer';
    import {createBottomTabNavigator} from '@react-navigation/bottom-tabs';
    import {HomeScreen, DetailsScreen, SettingScreen, MineScreen} from './Screen';
    
    const Stack = createStackNavigator();
    
    function StackScreen() {
      return (
        <Stack.Navigator
          screenOptions={{
            cardStyleInterpolator: CardStyleInterpolators.forHorizontalIOS,
          }}>
          <Stack.Screen name="Drawer" component={DrawerScreen} />
          <Stack.Screen name="Details" component={DetailsScreen} />
        </Stack.Navigator>
      );
    }
    
    const Drawer = createDrawerNavigator();
    
    function DrawerScreen() {
      return (
        <Drawer.Navigator>
          <Drawer.Screen name="Tab" component={TabScreen} />
          <Drawer.Screen name="Setting" component={SettingScreen} />
        </Drawer.Navigator>
      );
    }
    
    const Tab = createBottomTabNavigator();
    
    const TabBarIcon = (focused, color) => {
      return (
        <View
          style={{
            width: focused ? 24 : 18,
            height: focused ? 24 : 18,
            backgroundColor: color,
          }}
        />
      );
    };
    function TabScreen() {
      return (
        <Tab.Navigator
          tabBarOptions={{activeTintColor: '#FD7328', inactiveTintColor: '#999'}}
          screenOptions={{
            tabBarIcon: ({focused, color}) => {
              return TabBarIcon(focused, color);
            },
          }}>
          <Tab.Screen
            name="Home"
            component={HomeScreen}
            options={{title: '首页'}}
          />
          <Tab.Screen
            name="Mine"
            component={MineScreen}
            options={{title: '我的'}}
          />
        </Tab.Navigator>
      );
    }
    
    export default function App() {
      return (
        <NavigationContainer>
          <StackScreen />
        </NavigationContainer>
      );
    }
    
    

    登录权限认证

    v5版本之前可以使用createSwitchNavigator做登录身份认证,在V5版本移除了这个方法,可以使用V5新特性,根据状态定义和更改导航器的内容

    本次使用react Context进行管理,也可根据项目需要使用reduxmobx

    1.创建context

    import React from 'react';
    
    export const AuthContext = React.createContext();
    

    2.屏幕导航

    // screen
    export function SettingScreen() {
      const {signOut} = React.useContext(AuthContext);
      return (
        <BaseCenterView>
          <Text>设置</Text>
          <Button
            title="退出登录"
            onPress={() => {
              signOut();
            }}
          />
        </BaseCenterView>
      );
    }
    export function SignInScreen() {
      const {signIn} = React.useContext(AuthContext);
      return (
        <BaseCenterView>
          <Text>登录页面</Text>
          <Button
            title="登录"
            onPress={() => {
              signIn();
            }}
          />
        </BaseCenterView>
      );
    }
    export function SplashScreen() {
      return (
        <BaseCenterView>
          <Text>loading...</Text>
        </BaseCenterView>
      );
    }
    
    // Auth屏幕堆栈
    const AuthStack = createStackNavigator();
    const AuthStackScreen = () => (
      <AuthStack.Navigator headerMode="none">
        <AuthStack.Screen name="SignIn" component={SignInScreen} />
      </AuthStack.Navigator>
    );
    
    // APP堆栈
    const Drawer = createDrawerNavigator();
    function DrawerScreen() {
      return (
        <Drawer.Navigator>
          <Drawer.Screen name="Tab" component={TabScreen} />
          <Drawer.Screen name="Setting" component={SettingScreen} />
        </Drawer.Navigator>
      );
    }
    
    const Tab = createBottomTabNavigator();
    const TabBarIcon = (focused, color) => {
      return (
        <View
          style={{
            width: focused ? 24 : 18,
            height: focused ? 24 : 18,
            backgroundColor: color,
          }}
        />
      );
    };
    
    function TabScreen() {
      return (
        <Tab.Navigator
          tabBarOptions={{activeTintColor: '#FD7328', inactiveTintColor: '#999'}}
          screenOptions={{
            tabBarIcon: ({focused, color}) => {
              return TabBarIcon(focused, color);
            },
          }}>
          <Tab.Screen
            name="Home"
            component={HomeScreen}
            options={{title: '首页'}}
          />
          <Tab.Screen
            name="Mine"
            component={MineScreen}
            options={{title: '我的'}}
          />
        </Tab.Navigator>
      );
    }
    
    const MainStack = createStackNavigator();
    function MainStackScreen() {
      return (
        <MainStack.Navigator
          screenOptions={{
            cardStyleInterpolator: CardStyleInterpolators.forHorizontalIOS,
          }}>
          {/* <MainStack.Screen name="Drawer" component={DrawerScreen} /> */}
          <MainStack.Screen name="Home" component={HomeScreen} />
          <MainStack.Screen name="Details" component={DetailsScreen} />
        </MainStack.Navigator>
      );
    }
    
    // Root堆栈
    const RootStack = createStackNavigator();
    const RootStackScreen = ({userToken = false}) => (
      <RootStack.Navigator headerMode="none">
        {userToken ? (
          <RootStack.Screen
            name="App"
            component={MainStackScreen}
            options={{
              animationEnabled: false,
            }}
          />
        ) : (
          <RootStack.Screen
            name="Auth"
            component={AuthStackScreen}
            options={{
              animationEnabled: false,
            }}
          />
        )}
      </RootStack.Navigator>
    );
    
    // 主路由
    export default () => {
      const [isLoading, setIsLoading] = React.useState(true);
      const [userToken, setUserToken] = React.useState(null);
    
      const authContext = React.useMemo(() => {
        return {
          signIn: () => {
            setIsLoading(false);
            setUserToken('asdf');
          },
          signUp: () => {
            setIsLoading(false);
            setUserToken('asdf');
          },
          signOut: () => {
            setIsLoading(false);
            setUserToken(null);
          },
        };
      }, []);
    
      React.useEffect(() => {
        setTimeout(() => {
          setIsLoading(false);
        }, 1000);
      }, []);
      if (isLoading) {
        return <SplashScreen />;
      }
      return (
        <AuthContext.Provider value={authContext}>
          <NavigationContainer>
            <RootStackScreen userToken={userToken} />
          </NavigationContainer>
        </AuthContext.Provider>
      );
    };
    

    结束

    文章涉及代码:github

    相关文章

      网友评论

        本文标题:React Navigation5.X (Stack,Botto

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