【问题标题】:React Native - navigation issue "undefined is not an object (this.props.navigation.navigate)"React Native - 导航问题“未定义不是对象(this.props.navigation.navigate)”
【发布时间】:2017-06-21 14:11:29
【问题描述】:

我正在关注本教程 https://reactnavigation.org/docs/intro/,但遇到了一些问题。

我每次都使用 Expo Client 应用程序来渲染我的应用程序,而不是模拟器/模拟器。

我的代码如下所示。

我最初在“ChatScreen”组件上方定义了“SimpleApp”常量,但这给了我以下错误:

Route 'Chat' 应该声明一个屏幕。例如:...等

所以我将 SimpleApp 的声明移到“AppRegistry”上方,并标记了一个新错误

元素类型无效:预期的字符串.....您可能忘记导出您的组件..etc

本教程没有向任何组件添加关键词“导出默认值”,我认为这可能与我在 Expo 应用程序上运行它有关?所以我在“HomeScreen”中添加了“export default”,错误就消失了。

我似乎无法摆脱的新错误(基于下面的代码)如下:

undefined 不是对象(评估 'this.props.navigation.navigate')

除非我删除“const {navigate}”周围的“{}”,否则我无法摆脱它,但是当我从主屏幕按下按钮时会破坏导航

import React from 'react';
import {AppRegistry,Text,Button} from 'react-native';
import { StackNavigator } from 'react-navigation';

export default class HomeScreen extends React.Component {
  static navigationOptions = {
    title: 'Welcome',
  };
  render() {
    const { navigate } = this.props.navigation;
    return (
      <View>
        <Text>Hello, Chat App!</Text>
        <Button
          onPress={() => navigate('Chat')}
          title="Chat with Lucy"
        />
      </View>
    );
  }
}



class ChatScreen extends React.Component {
  static navigationOptions = {
    title: 'Chat with Lucy',
  };
  render() {
    return (
      <View>
        <Text>Chat with Lucy</Text>
      </View>
    );
  }
}

const SimpleApp = StackNavigator({
  Home: { screen: HomeScreen },
  Chat: { screen: ChatScreen },
});
AppRegistry.registerComponent('SimpleApp', () => SimpleApp);

【问题讨论】:

  • 似乎 this.props.navigation 在首次渲染时未定义。您可以尝试删除行 const { navigate } = this.props.navigation; 并使用 onPress={() =&gt; this.props.navigation.navigate('Chat')} 以便稍后才能访问该对象。
  • 我试过了,我被提示按下按钮,但是当我这样做时,我遇到了这个错误,“未定义不是一个对象(评估'_this2.props.navigation.navigate') " 我确实安装了 react-navigation npm 模块
  • 对我来说导航工作正常,只需要从 react-native 导入 View,但我没有在 Expo 中运行它。
  • 如果我将导航 API 设计得尽可能地迟钝和脆弱,那么 React 导航就不能做得更糟了。

标签: javascript reactjs react-native expo


【解决方案1】:

附加信息: 当您嵌套子组件时,您需要在父组件中将导航作为道具传递。 //父.js &lt;childcomponent navigation={this.props.navigation}/&gt;

你可以像这样访问导航

//child.js

this.props.navigation.navigate('yourcomponent');

参考:https://reactnavigation.org/docs/en/connecting-navigation-prop.html

【讨论】:

  • 谢谢。这确实帮助我在最初与 react-native 的斗争中解决了未定义的错误
  • 这对我有用,谢谢!我假设因为我为我的组件创建了一个屏幕,它将接收props.navigation,但这不是因为该组件嵌套在另一个组件中,不知道为什么会这样。所以我就像你说的那样通过了。
  • 哎呀,我不喜欢这样做,也许将它放在上下文中会很好。编辑:我们可以调用useNavigation,这很好,因为我们不必向下传递组件层次结构
【解决方案2】:

使用 Expo,您不应该自己进行应用注册,而是应该让 Expo 来完成,请记住,您必须始终导出默认组件: 您还需要从 react-native 导入 View 和 Button:请在下面找到完整代码:

import React from 'react';
import {
  AppRegistry,
  Text,
  View,
  Button
} from 'react-native';
import { StackNavigator } from 'react-navigation';

 class HomeScreen extends React.Component {
  static navigationOptions = {
    title: 'Welcome',
  };
  render() {
    const { navigate } = this.props.navigation;
    return (
      <View>
        <Text>Hello, Chat App!</Text>
        <Button
          onPress={() => navigate('Chat', { user: 'Lucy' })}
          title="Chat with Lucy"
        />
      </View>
    );
  }
}

 class ChatScreen extends React.Component {
  // Nav options can be defined as a function of the screen's props:
  static navigationOptions = ({ navigation }) => ({
    title: `Chat with ${navigation.state.params.user}`,
  });
  render() {
    // The screen's current route is passed in to `props.navigation.state`:
    const { params } = this.props.navigation.state;
    return (
      <View>
        <Text>Chat with {params.user}</Text>
      </View>
    );
  }
}

const  SimpleAppNavigator = StackNavigator({
  Home: { screen: HomeScreen },
  Chat: { screen: ChatScreen }
});

const AppNavigation = () => (
  <SimpleAppNavigator  />
);

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

【讨论】:

  • 非常感谢!有效!您能否详细说明我不应该自己使用 expo 进行 appregistration 的部分?只是为了确认一下,我总是需要导出一个默认组件,它最初会被渲染吗?另外,您制作 AppNavigation 和 SimpleAppNavigator 实例的任何原因?这是最佳做法吗?
  • 所以通常如果你在没有 Expo 的情况下进行测试,你会注册你的应用程序,例如:AppRegistry.registerComponent('SimpleApp', () =&gt; SimpleApp); 但是使用 Expo 它将默认导出根组件,并将在 Expo 应用程序中显示它: '导出默认类 App 扩展 React.Component { render() { return ( ); } }' 不要忘记将答案标记为正确答案。
  • 完成!您能否解释一下为什么将 simpleAppNavigator 放入 AppNavigation 中,然后再渲染到不同的组件中?这是最佳做法吗?
  • 在这里它可能看起来并不重要..但一般来说你想要这种分离..因为你的导航器可能在另一个文件中只关心这部分路由..但你的导航可能已经扩展例如,使用 redux 与商店绑定的逻辑......以及导航可以包括一个选项卡导航器和几个堆栈导航器的组合。
  • @AhmedKhaledA.Mohamed 你是神。 reactnavigation.org/docs/intro 这里的文档已经过时了,而且这个例子是开箱即用的。你应该是为他们写例子的人哈哈。在这个错误上花了几个小时。互联网上的每个人都在问这个问题,并且非常困惑并且在转圈。谢啦!! (23 小时内给你赏金)
【解决方案3】:

正如 Bobur 在他的回答中所说,导航道具不会传递给路由组件的子组件。要让您的组件访问navigation,您可以将其作为道具传递给它们,但有更好的方法。

如果您不想将 navigation 属性一直传递到组件层次结构中,则可以改用 useNavigation。 (在我看来,这更简洁,并且减少了我们必须编写的代码量):

function MyBackButton() {
  const navigation = useNavigation();

  return (
    <Button
      title="Back"
      onPress={() => {
        navigation.goBack();
      }}
    />
  );
}

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

这真的很好,因为如果您有多个级别的组件,您将不必连续传递导航对象作为道具来使用它。只传递一次navigation 需要我们 1. 向我们想要传递它的组件添加一个 prop。 2.从父组件传递prop。 3. 使用navigation 属性进行导航。有时我们必须重复第 1 步和第 2 步才能将 prop 一直向下传递到需要使用 navigation 的组件。我们可以将第 1 步和第 2 步,无论它们重复多少次,都可以用这个方法压缩成一个 useNavigation 调用。

我认为这是最好的。

【讨论】:

    【解决方案4】:

    试试这个代码:onPress={() =&gt; this.props.navigation.navigate('Chat')}

    【讨论】:

      【解决方案5】:

      navigation={props.navigation} {...data} />

      这将使导航从父导航传播到后续子导航。

      【讨论】:

        【解决方案6】:
        const AppNavigation =()=>{  <SimpleApp  />}
        
        export default class App extends React.Componet{
           render(){
              return (
                <AppNavigation/>
             );
          }
        }
        

        【讨论】:

        • 考虑为您的答案添加解释。
        • 并从您的代码中删除错字:“Componet”...
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-05-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多