反应本机导航错误:任何导航器都未处理使用有效负载 {"name": 192.168.100.189:19000", "params":{}} 导航的操作

pre*_*ton 13 javascript android reactjs react-native react-navigation

我在 React Native 应用程序中使用 react-navigation。

我不断收到一个错误,该错误应该是仅用于开发的警告,不会在生产中显示。

我如何修复下面的错误?

console.error: "The action 'NAVIGATE' with payload
{"name":"192.168.100.189:19000","params":{}} was not handled by any
navigator.

Do you have a screen named '192.168.100.189:19000'?

If you'r trying to navigate to a screen in a nested navigator, see
https://reactnavigation.org/docs/nesting-navigators#navigating-to-a-screen-in-a-nestd-navigator.

This is a development-only warning and won't be shown in production."
Run Code Online (Sandbox Code Playgroud)

Ish*_*nha 18

正如我的情况一样,如果您尝试导航到嵌套导航器中的屏幕(如错误中所述),您确实需要检查https://reactnavigation.org/docs/nesting-navigators上的文档#navigating-to-a-screen-in-a-nestd-navigator(再次在错误中提到):

考虑以下示例:

function Root() {
  return (
    <Stack.Navigator>
      <Stack.Screen name="Profile" component={Profile} />
      <Stack.Screen name="Settings" component={Settings} />
    </Stack.Navigator>
  );
}

function App() {
  return (
    <NavigationContainer>
      <Drawer.Navigator>
        <Drawer.Screen name="Home" component={Home} />
        <Drawer.Screen name="Root" component={Root} />
      </Drawer.Navigator>
    </NavigationContainer>
  );
}
Run Code Online (Sandbox Code Playgroud)

在这里,您可能想RootHome组件导航到堆栈:

navigation.navigate('Root');
Run Code Online (Sandbox Code Playgroud)

Root它可以工作,并显示组件内的初始屏幕,即Profile。但有时您可能想要控制导航时应显示的屏幕。要实现它,您可以在参数中传递屏幕的名称:

navigation.navigate('Root', { screen: 'Settings' });
Run Code Online (Sandbox Code Playgroud)

现在,Settings屏幕将被渲染,而不是Profile在导航时渲染。

这可能看起来与以前用于嵌套屏幕的导航方式非常不同。不同之处在于,在以前的版本中,所有配置都是静态的,因此 React Navigation 可以通过递归到嵌套配置来静态找到所有导航器及其屏幕的列表。但通过动态配置,React Navigation 不知道哪些屏幕可用以及在哪里,直到包含屏幕的导航器呈现。通常,在您导航到屏幕之前,屏幕不会呈现其内容,因此尚未呈现的导航器的配置尚不可用。这使得有必要指定您要导航到的层次结构。这也是为什么您应该尽可能少地嵌套导航器以使代码更简单。


Tad*_*she 10

这里可能会发生两件事:

在我的情况下:我有不同的函数返回单独的堆栈导航器,如下面的代码所示,我希望在SettingsScreen用户第一次使用应用程序时出现,以便他们设置配置,下次他们再次打开应用程序时他们会首先查看主屏幕(与身份验证相同的流程)

function SettingsStack() {
  return (
    <Stack.Navigator initialRouteName='Settings'>
      <Stack.Screen
        name="Settings"
        component={SettingsScreen}
        options={{
          title: 'SMS Recipient Number',
          headerShown: true,
          headerTitleAlign: 'center',
        }}
      />
      <Stack.Screen name="Home" component={HomeScreen} options={{ title: '', headerTransparent: true }}
      />
    </Stack.Navigator>
  );
}

function MainStack() {
  return (
    <Stack.Navigator initialRouteName='Home'>
      <Stack.Screen
        name="Update"
        component={UpdateScreen}
        options={{
          title: 'Update Recipient Phone',
          headerTitleAlign: 'center',
          headerShown: true
        }}
      />
      <Stack.Screen
        name="Security"
        component={PinScreen}
        options={{
          title: 'Provide PIN',
          headerTitleAlign: 'center',
          headerShown: true
        }}
      />
      <Stack.Screen
        name="Home"
        headerMode="screen"
        component={HomeScreen}
        options={({ navigation }) => ({
          headerTitle: '',
          headerTransparent: true,
          headerRight: () => (
            <Button
              icon={
                <Icon
                  name='settings'
                  type='feather'
                  color='grey'
                  onPress={() => navigation.navigate('Update')}
                  onLongPress={() => navigation.navigate('Update')}
                />
              }
              type="clear"
              buttonStyle={{ marginRight: 10 }}
            />
          ),
        })}
      />
    </Stack.Navigator>
  );
}
Run Code Online (Sandbox Code Playgroud)

设置屏幕:在用户提供所需详细信息后的设置屏幕内,我使用以下功能重定向到HomeScreen

transactEntry = async () => {
    const { phone_number } = this.state;

    if ((this.state.phone_number.trim() == "") || (this.state.phone_number.trim().length == 0)) {
        Alert.alert('Error:', 'Please enter valid phone number.');
        return
    }

    try {
        await AsyncStorage.setItem('@recipient_number', phone_number);
    } catch (error) {
        Alert.alert('Error:', 'Error setting recipient phone number!');
    }

    Keyboard.dismiss();

    let successToast = Toast.show('Recipient phone number set successfully.', {
        duration: Toast.durations.LONG,
        position: Toast.positions.TOP,
        shadow: true,
        animation: true,
        backgroundColor: 'black',
        hideOnPress: true,
        delay: 0,
        onShow: () => { },
        onShown: () => { },
        onHide: () => { },
        onHidden: () => { }
    });

    setTimeout(function () {
        Toast.hide(successToast);
    }, 3000);

    successToast;
    this.props.navigation.replace('Home');

};
Run Code Online (Sandbox Code Playgroud)

注意:this.props.navigation.replace('Home');SettingsScreen 中使用的部分。这可以正常工作,但是被调用的Home 路由来自该function SettingsStack() {...}函数而不是该function MainStack() {...}函数。

因此,来自堆栈顶部的Home Route 的所有导航都会给我这样一个错误,因为我的活动堆栈只有两条路线,Settings RouteHome Route

后来我意识到我正在强迫我的应用程序查找位于不同堆栈中的路由,因此我重新function MainStack() {...}连接了它并将其与function SettingsStack() {...}如下功能链接。

function SettingsStack() {
  return (
    <Stack.Navigator initialRouteName='Settings'>
      <Stack.Screen
        name="Settings"
        component={SettingsScreen}
        options={{
          title: 'SMS Recipient Number',
          headerShown: true,
          headerTitleAlign: 'center',
        }}
      />
      <Stack.Screen name="MainStack" component={MainStack} options={{ title: '', headerTransparent: true }}
      />
    </Stack.Navigator>
  );
}

function MainStack() {
  return (
    <Stack.Navigator initialRouteName='Home'>
      <Stack.Screen
        name="Update"
        component={UpdateScreen}
        options={{
          title: 'Update Recipient Phone',
          headerTitleAlign: 'center',
          headerShown: true
        }}
      />
      <Stack.Screen
        name="Security"
        component={PinScreen}
        options={{
          title: 'Provide PIN',
          headerTitleAlign: 'center',
          headerShown: true
        }}
      />
      <Stack.Screen
        name="Home"
        headerMode="screen"
        component={HomeScreen}
        options={({ navigation }) => ({
          headerTitle: '',
          headerTransparent: true,
          headerRight: () => (
            <Button
              icon={
                <Icon
                  name='settings'
                  type='feather'
                  color='grey'
                  onPress={() => navigation.navigate('Update')}
                  onLongPress={() => navigation.navigate('Update')}
                />
              }
              type="clear"
              buttonStyle={{ marginRight: 10 }}
            />
          ),
        })}
      />
    </Stack.Navigator>
  );
}
Run Code Online (Sandbox Code Playgroud)

<Stack.Screen name="MainStack" component={MainStack} options={{ title: '', headerTransparent: true }} />MainStack 现在连接到 SettingsStack 的那一行。

简而言之:确保您调用的路由与调用路由位于同一堆栈中,或者只需确保您以某种方式连接了路由,例如将堆栈函数放在抽屉导航器函数中。至少必须有关系或加入。

  • 考虑用几行关键行来回答,而不是按原样粘贴大量代码。 (17认同)

小智 8

我的问题最终通过删除 Stack.Screen 名称中的空格来解决。


小智 7

我遇到了同样的问题,谷歌搜索将我带到了这个页面。然后,我不小心将“name”道具命名为与组件相同的名称,错误消失了,我的导航器开始正常工作。我将名称更改为其他名称,然后返回错误。因此,名称 prop 似乎必须与组件的名称相同。就像这样:

<Stack.Screen
        name="SettingsScreen"
        component={SettingsScreen}
        options={{
          title: 'SMS Recipient Number',
          headerShown: true,
          headerTitleAlign: 'center',
        }} />
Run Code Online (Sandbox Code Playgroud)


Ben*_*rth 0

React 导航允许应用程序更改向用户显示的组件。navigation.navigate('192.168.100.189:19000')您在代码中的某个地方调用吗?这不是 React Navigation 的目的。导航的参数应该是屏幕名称:具体来说,是您提供给 Navigator.Screen 组件的名称:

<Stack.Screen name="Your Camera" component={Camera} />
Run Code Online (Sandbox Code Playgroud)

navigation.navigate('Your Camera')会将应用程序导航到相机组件。

如果您希望用户在浏览器中打开 URL,那么您应该使用Linking library, Linking.openURL('192.168.100.189:19000')

PS:params 对象是可选的。如果您要传递一个空对象,则它不需要在那里。