GVKun编程网logo

React Navigation 入门(四) - 屏幕导航 Navigation 属性详解(react menu 导航)

15

在本文中,我们将为您详细介绍ReactNavigation入门的相关知识,并且为您解答关于四-屏幕导航Navigation属性详解的疑问,此外,我们还会提供一些关于@react-navigation/

在本文中,我们将为您详细介绍React Navigation 入门的相关知识,并且为您解答关于四 - 屏幕导航 Navigation 属性详解的疑问,此外,我们还会提供一些关于@ react-navigation / native和@ react-navigation / stack读取整个堆栈、initialProps被React-Navigation的navigation属性覆盖解决方案、javascript – undefined不是函数(评估’_reactNavigation.NavigationActions.reset’)、React Native Navigation V5 Stack、BottomTab 和 Drawer Navigation的有用信息。

本文目录一览:

React Navigation 入门(四) - 屏幕导航 Navigation 属性详解(react menu 导航)

RN 版本:0.50
操作环境:Windows 10
React Navigation 版本:1.0.0-beta.20

文章同步自简书:http://www.jianshu.com/p/6d178490b164

之前已经说过,每个在 navigator 中注册过的页面都会接受一个 navigation 属性,它包含以下几属性:

  • navigate - (helper) 连接其他页面
  • state - 页面当前的状态/路由
  • setParams - (helper) 更新路由的参数
  • goBack - (helper) 关闭当前活动页面并返回
  • dispatch - 给路由器发送指令行为

在之前的几篇文章中,我们已经接触过 navigate (用来跳转页面)、state(用来获取传递的参数)和 setParams(用来改变参数),这篇文章将会对它们进行更详细的说明。

注意:navigation 属性被传递给了每一个导航相关组件并且包括导航器。不过需要注意的不同点是导航器 navigator 的 navigation 属性不会包含那些 helper 类的函数(navigate,goBack 等),它只有 statedispatch 属性。如果你想要使用导航器 navigation 属性中的 navigate 函数,你必须使用 dispatch 来传递一个导航操作意图(关于 Navigation Actions 下一篇文章会讲)。

与 Redux 集成时的注意事项

注:这段文字直接翻译自官方文档,由于我还没有了解过 redux,所以看得不是太懂。有兴趣的可以看看 原文。

由于许多人对 navigator 顶级 API 的理解错误,他们并不能很好地正确使用 navigation 属性与 redux 的关联。导航器 navigator 如果没有接收到 navigation 属性话它会保持自己的状态,但这个并不是你通常情况下关联 redux 时想要的特征。对于嵌套在主导航器里面的各个导航器,你总是会想把 navigation 属性传递下去。这就允许你的顶级导航器去传达并给子导航器提供状态。这个时候你只需要将顶级路由与 redux 集成,因为其他的路由都被包含在了它的里面。

在 app 中跳转其它页面时调用的方法。它有如下参数:

navigate(routeName,params,action)

  • routeName - 在你的 app 中已经注册过的打算跳转的目的路由名称
  • params - 传给目的路由的参数
  • action - (高级)如果屏幕是导航器,则在子路由中运行的操作。有关支持的操作的完整列表,请参阅 操作文档,暂时打算下一篇文章再介绍。
class HomeScreen extends React.Component {
  render() {
    const {navigate} = this.props.navigation;
    return (
      <View>
        <Text>This is the home screen of the app</Text>
        <Button
          // 跳转到 Profile 页面并传递参数 name
          onPress={() => navigate('Profile',{name: 'Brent'})}
          title="Go to Brent's profile"
        />
      </View>
     )
   }
}

state - 屏幕当前状态/路由

一个屏幕可以通过 this.props.navigation.state 获取它的路由,它返回的是一个如下类型的对象:

{
  // the name of the route config in the router
  // 路由器中设置的路由名称
  routeName: 'Profile',// a unique identifier used to sort routes
  // 为方便管理路由而产生的唯一标识
  key: 'main0',// an optional object of string options for this screen
  // 给当前屏幕可供选择的参数对象
  params: { hello: 'world' }
}
class ProfileScreen extends React.Component {
  render() {
    const {state} = this.props.navigation;
    // state.routeName === 'Profile'
    return (
      // 获取参数 name,我们之前已经见到过这种用法了
      <Text>Name: {state.params.name}</Text>
    );
  }
}

setParams - 改变路由参数

触发 setParams 方法允许页面改变路由中的参数,这对于更新头部标题及按钮很有用处。上一篇文章中我们曾经介绍过这个方法。

class ProfileScreen extends React.Component {
  render() {
    const {setParams} = this.props.navigation;
    return (
      <Button
        onPress={() => setParams({name: 'Lucy'})}
        title="Set title name to 'Lucy'"
      />
     )
   }
}

goBack - 关闭当前活动页面并返回

给该方法提供一个 key,来决定要从哪个路由返回(即要关闭哪个页面)。默认情况下,会关闭掉调用该方法的当前路由。如果目标是想要回到 anywhere 而不具体地说明要关闭哪个页面,可以调用 goBack(null)

class HomeScreen extends React.Component {
  render() {
    const {goBack} = this.props.navigation;
    return (
      <View>
        <Button
          // 关闭当前的 HomeScreen
          onPress={() => goBack()}
          title="Go back from this HomeScreen"
        />
        <Button
          // 这里测试的结果也是关闭了当前的 HomeScreen
          onPress={() => goBack(null)}
          title="Go back anywhere"
        />
        <Button
          // 关闭从 'screen-123' 到栈顶的所有路由
          onPress={() => goBack('screen-123')}
          title="Go back from screen-123"
        />
      </View>
     )
   }
}

从指定的页面返回

假设我们有四个路由 A B C D 依次入栈:

navigation.navigate(SCREEN_KEY_A);
...
navigation.navigate(SCREEN_KEY_B);
...
navigation.navigate(SCREEN_KEY_C);
...
navigation.navigate(SCREEN_KEY_D);

假如你在 screen D 并且想要返回到 screen A(关闭 D,C 和 B),那么你就需要这么写:

// will go to screen A FROM screen B
navigation.goBack(SCREEN_KEY_B)

注意:这个方法里面的 key 值,并不是定义 navigator 时我们给页面自定义的 key,而是上面 state 里面的 state.key。并且我们在 D 中不能直接通过 this.props.navigation.state.key 来获取,因为它获取的是 D 的 key,所以我们要在 B 中获取到它,然后一级一级的传递给 D,最后调用 navigation.goBack(SCREEN_KEY_B) 来回到 A。

dispatch - 给路由发送一个行为

使用 dispatch 给路由指派任意的 navigation 行为,其它的 navigation 函数使用后台的 dispatch 来实现。记住如果你想指派 react-navigation 行为的话,你应该使用库里提供的 action creators。查看 Navigation Actions 来获取完整的可指派行为(具体行为会在下一篇文章进行说明)。

import { NavigationActions } from 'react-navigation'

const navigateAction = NavigationActions.navigate({
  routeName: 'Profile',params: {},// navigate can have a nested navigate action that will be run inside the child router
  // navigate 可以嵌套 navigate action,它会在子路由里面执行
  action: NavigationActions.navigate({ routeName: 'SubProfileRoute'})
})
this.props.navigation.dispatch(navigateAction)
@H_682_301@

总结

以上是小编为你收集整理的React Navigation 入门(四) - 屏幕导航 Navigation 属性详解全部内容。

如果觉得小编网站内容还不错,欢迎将小编网站推荐给好友。

@ react-navigation / native和@ react-navigation / stack读取整个堆栈

@ react-navigation / native和@ react-navigation / stack读取整个堆栈

您可以使用如下所示的useNavigationState钩子来获取当前状态

https://reactnavigation.org/docs/use-navigation-state/

import {useNavigationState} from '@react-navigation/native';

const state = useNavigationState((state) => state);

alert(JSON.stringify(state.routes));

这将在路线中显示屏幕

initialProps被React-Navigation的navigation属性覆盖解决方案

initialProps被React-Navigation的navigation属性覆盖解决方案

怎么开场对我来说一个是个很纠结的问题,Emmm这应该算个好开场。
最近在做一个RN的app端调试工具,在把它嵌入原生app中的时候遇到了一个问题,RN组件里面接受不到原生传过来的initialProps?!


先po一下问题原因和答案,看官们有兴趣的话可以再看看下面的废话。
问题原因:首先看下我们一般怎么写,

const AppWithDebug = createStackNavigator({
  Home: {
    screen: App
  },
  ...debugRoute
});

AppRegistry.registerComponent(appName, () => AppWithDebug);

一般情况下,我们会把createStackNavigator生成的对象,作为AppRegistry.registerComponent的入口文件,这个时候react-navigation在接收到initialProps之后并不会向下传递,而是只向下传递自身的navigation对象内容因此这个时候我们在组件中就拿不到原生传过来的initialProps内容了。
解决方案:隔离入口,不再使用createStackNavigator的结果去作为AppRegistry.registerComponent的入口,如

const AppWithDebug = createStackNavigator({
  Home: {
    screen: App
  },
  ...debugRoute
});

class AppEntry extends Component {
    render() {
      return <AppWithDebug screenProps={ this.props }/>
  }
};

AppRegistry.registerComponent(appName, () => AppEntry);

react-navigation不再处于项目入口的位置,入口处由一个包含了导航组件的组件代替。此时我们在AppEntry组件中就可以直接通过this.props拿到initialProps的值了,再通过screenProps向下传递即可,AppWithDebug中可以通过this.props.screenProps获取initialProps的相关内容。
~~问题解决~~以下是爬坑过程~~


碰到这个问题第一反应,什么鬼?官方文档是这么介绍的啊,

这里的initialProperties注入了一些演示用的数据。在 React Native 的根组件中,我们可以使用this.props来获取到这些数据。--RN中文网
RCTRootView *rootView =
[[RCTRootView alloc] initWithBundleURL: jsCodeLocation
      moduleName: @"RNHighScores"
initialProperties:
 @{
   @"scores" : @[
     @{
       @"name" : @"Alex",
       @"value": @"42"
      },
     @{
       @"name" : @"Joel",
       @"value": @"10"
     }
   ]
 }
   launchOptions: nil];
注:请忽略我的强行缩进,节省点大家横向拖动的时间

文档写的明明白白,难道我是个傻子?你传过来,我直接this.props.xxx,一点毛病没有啊,为啥拿不到?在去原生同学那里一看他们的demo获取正常。。。

这个时候就准备在自己的项目上开始各种骚操作尝试一下,但是没等我大展拳脚就发现自己可能掉进react-navigation的坑里了,因为最开始去获取initialProps的时候打印了一下this.props对象,发现只有navigation一个子属性,于是就把导航去掉试了一下发现initialProps的属性居然就蹦出来了,这个时候基本就可以确定问题出在react-navigation上了。
这个时候去react-navigation的github官网上查一下issue,就发现了这个

看样子楼主遇到了一样的问题,并且真的是一步一步的证明了react-navigation在这个上面的bug,但第一次看了一圈没找到答案,直到第二次才找到答案

看到这里,真的是恍然大悟,你应该也明白了吧~其实就是隔离入口

经常看到结论,会恍然大悟“哦 原来就这样啊 这么简单”。
其实很多时候答案并不复杂,我们所或缺的是思考问题的方法,之所以写答案下面的这些”废话“,也是最近特别烦躁,经常会被问题卡住并且变得更烦躁,想给自己提个醒,让自己静一静。
目前的开发工作,除非是原创性的工作,一般情况下你遇到的问题都是别人遇到过的,只要去找,可能会很长时间,但终归还是可以解决的,github的issue是个找答案的好地方,耐心寻找。
烦躁并不能解决问题,只会扰乱你的思路,所以不要被情绪左右你的理智。
~加油 你是最胖的~

javascript – undefined不是函数(评估’_reactNavigation.NavigationActions.reset’)

javascript – undefined不是函数(评估’_reactNavigation.NavigationActions.reset’)

我想在特定超时后将启动画面导航到下一个屏幕.启动画面有一个动画,在Airbnb Lottie的帮助下为React Native完成.

splashscreen代码如下:

import React from "react";
import { Animated,Easing } from "react-native";
import LottieView from "lottie-react-native";
import { NavigationActions } from "react-navigation";

export default class SplashScreen extends React.Component {
  static navigationoptions = {
    header: null
  };

  constructor() {
    super();
    this.state = {
      progress: new Animated.Value(0),}
  }

  componentDidMount() {
    setTimeout(() => {
      this.navigatetoWalkthrough()
    },3500);
    
    Animated.timing(this.state.progress,{
      tovalue: 1,duration: 3000,easing: Easing.linear,}).start();
  }

  navigatetoWalkthrough = () => {
    const navigateAction = NavigationActions.reset({
      index: 0,actions: [NavigationActions.navigate({ routeName: "Walkthrough" })],});

    this.props.navigation.dispatch(navigateAction);
  }

  render() {
    return(
      <LottieView 
      source={require("../assets/splash/SplashScreenAnimation.json")}
      progress={this.state.progress}
      />
    );
  }
}

我运行应用程序后出现错误:

undefined is not a function (evaluating'_reactNavigation.NavigationActions.reset')

Main.js文件如下所示:

import React from "react";
import { View,Text } from "react-native";
import { createStackNavigator } from "react-navigation";

import SplashScreen from "./screens/SplashScreen";
import Walkthrough from "./screens/Walkthrough";

const Routes = createStackNavigator({
  Home: {
    screen: SplashScreen
  },Walkthrough: {
    screen: Walkthrough
  }
});

export default class Main extends React.Component {
  render() {
    return <Routes />;
  }
}

任何帮助/反馈?

解决方法

从NavigationActions中删除了重置操作,并且在反应导航的v2中有特定于StackNavigator的 StackActions.

StackActions is an object containing methods for generating actions
specific to stack-based navigators. Its methods expand upon the
actions available in NavigationActions.

The following actions are supported:

Reset – Replace current state with a new state

Replace – Replace a route at a given key with another route

Push – Add a route on the top of the stack,and navigate forward to it

Pop – Navigate back to prevIoUs routes

PopToTop – Navigate to the top route of the stack,dismissing all other routes

React Native Navigation V5 Stack、BottomTab 和 Drawer Navigation

如何解决React Native Navigation V5 Stack、BottomTab 和 Drawer Navigation?

我在我的项目中使用了底部、堆栈和抽屉导航。

我需要导航到事件页面而不添加到底部导航器。

我的问题:

如果我需要将一个组件导航到另一个组件而不将组件添加到底部导航器,这里给出了两个文件的代码 如果需要导航到事件页面,如果我在 Component 我可以导航到 Events Compnents。但它也在底部选项卡导航器中显示我不希望底部导航器中的这个组件。

App.js

import ''react-native-gesture-handler'';
    import { StatusBar } from ''expo-status-bar'';
    import React from ''react'';
    import { StyleSheet,Text,View } from ''react-native'';
    import { NavigationContainer } from ''@react-navigation/native'';
    import { createDrawerNavigator } from ''@react-navigation/drawer'';
    import {DrawerContent} from ''./Screens/DrawerContent'';
    import {Events} from ''./Screens/Events''
    import MainTabScreen from ''./Screens/Bottomtab''
    
    const Drawer = createDrawerNavigator();
    
    
    
    export default function App() {
      return (
        <NavigationContainer>
          <Drawer.Navigator drawerContent={props => <DrawerContent {...props} />}>
            <Drawer.Screen name="Home" component={MainTabScreen} />
          </Drawer.Navigator>
        </NavigationContainer>
      );
    }
    
    const styles = StyleSheet.create({
      container: {
        flex: 1,backgroundColor: ''#fff'',alignItems: ''center'',justifyContent: ''center'',},});```
    
    BottomTab Screen.js
    
        enter code here
    
    ```
    import React from "react";
    import { createStackNavigator } from "@react-navigation/stack";
    import Icon from "react-native-vector-icons/Ionicons";
    import { createMaterialBottomTabNavigator } from "@react-navigation/material-bottom-tabs";
    
    import Home from "./HomeScreen";
    import About from "./AboutUs";
    import Contact from "./ContactUs";
    import Test from "./Test";
    import Events from "./Events";
    
    const HomeStack = createStackNavigator();
    const AboutStack = createStackNavigator();
    const ContactStack = createStackNavigator();
    const TestStack = createStackNavigator();
    const Eventsstack = createStackNavigator();
    
    const Tab = createMaterialBottomTabNavigator();
    
    const MainTabScreen = () => (
      <Tab.Navigator
        initialRouteName="Home"
        activeColor="#fff"
        //   style={{ backgroundColor: ''tomato'' }}
      >
        <Tab.Screen
          name="Home"
          component={HomeStackScreen}
          options={{
            tabBarLabel: "Home",tabBarColor: "#009387",tabBarIcon: ({ color }) => (
              <Icon name="ios-home" color={color} size={26} />
            ),}}
        />
        <Tab.Screen
          name="ContactUs"
          component={ContactStackScreen}
          options={{
            tabBarLabel: "Notifications",tabBarColor: "#1f65ff",tabBarIcon: ({ color }) => (
              <Icon name="ios-notifications" color={color} size={26} />
            ),}}
        />
        <Tab.Screen
          name="About"
          component={AboutStackScreen}
          options={{
            tabBarLabel: "Profile",tabBarColor: "#694fad",tabBarIcon: ({ color }) => (
              <Icon name="ios-person" color={color} size={26} />
            ),}}
        />
        <Tab.Screen
          name="Test"
          component={TestStackScreen}
          options={{
            tabBarLabel: "Search",tabBarColor: "#d02860",tabBarIcon: ({ color }) => (
              <Icon name="ios-aperture" color={color} size={26} />
            ),}}
        />
    
        {/* <Tab.Screen
          name="Events"
          component={EventsstackScreen}
          options={{
            tabBarLabel: "Search",}}
        /> */}
      </Tab.Navigator>
    );
    export default MainTabScreen;
    
    const HomeStackScreen = ({ navigation }) => (
      <HomeStack.Navigator
        screenoptions={{
          headerStyle: {
            backgroundColor: "#009387",headerTintColor: "#fff",headerTitleStyle: {
            fontWeight: "bold",}}
      >
        <HomeStack.Screen
          name="Home"
          component={Home}
          options={{
            title: "Home",headerLeft: () => (
              <Icon.Button
                name="ios-menu"
                size={25}
                backgroundColor="#009387"
                onPress={() => navigation.openDrawer()}
              ></Icon.Button>
            ),}}
        />
      </HomeStack.Navigator>
    );
    
    const ContactStackScreen = ({ navigation }) => (
      <ContactStack.Navigator
        screenoptions={{
          headerStyle: {
            backgroundColor: "#1f65ff",}}
      >
        <ContactStack.Screen
          name="ContactUs"
          component={Contact}
          options={{
            title: "ContactUs",headerLeft: () => (
              <Icon.Button
                name="ios-menu"
                size={25}
                backgroundColor="#1f65ff"
                onPress={() => navigation.openDrawer()}
              ></Icon.Button>
            ),}}
        />
      </ContactStack.Navigator>
    );
    const AboutStackScreen = ({ navigation }) => (
      <AboutStack.Navigator
        screenoptions={{
          headerStyle: {
            backgroundColor: "#694fad",}}
      >
        <AboutStack.Screen
          name="About"
          component={About}
          options={{
            title: "AboutUs",headerLeft: () => (
              <Icon.Button
                name="ios-menu"
                size={25}
                backgroundColor="#694fad"
                onPress={() => navigation.openDrawer()}
              ></Icon.Button>
            ),}}
        />
      </AboutStack.Navigator>
    );
    const TestStackScreen = ({ navigation }) => (
      <TestStack.Navigator
        screenoptions={{
          headerStyle: {
            backgroundColor: "#d02860",}}
      >
        <TestStack.Screen
          name="Test"
          component={Test}
          options={{
            title: "Test",headerLeft: () => (
              <Icon.Button
                name="ios-menu"
                size={25}
                backgroundColor="#d02860"
                onPress={() => navigation.openDrawer()}
              ></Icon.Button>
            ),}}
        />
      </TestStack.Navigator>
    );
    const EventsstackScreen = ({ navigation }) => (
      <Eventsstack.Navigator screenoptions={{
          headerStyle: {
            backgroundColor: "#d02860",}}
      >
        <Eventsstack.Screen
          name="Events"
          component={Events}
          options={{
            title: "Events",}}
        />
      </Eventsstack.Navigator>
    );

这里给出了两个文件的代码如果需要导航到事件页面,如果我在 组件中声明事件组件,我将无法导航我可以导航到事件组件。但它也显示在底部选项卡中导航器我不想在底部导航器中使用这个组件。

我需要调用 EventsstackScreen 而不添加到

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

今天关于React Navigation 入门四 - 屏幕导航 Navigation 属性详解的介绍到此结束,谢谢您的阅读,有关@ react-navigation / native和@ react-navigation / stack读取整个堆栈、initialProps被React-Navigation的navigation属性覆盖解决方案、javascript – undefined不是函数(评估’_reactNavigation.NavigationActions.reset’)、React Native Navigation V5 Stack、BottomTab 和 Drawer Navigation等更多相关知识的信息可以在本站进行查询。

本文标签: