首页 > 解决方案 > 带有有效负载 {"name":"Home","params":{} 的操作 'NAVIGATE' 未被任何导航器处理

问题描述

当前行为 应用程序应在登录或登录到主页后重定向用户,但它会抛出此错误

应用程序.js:

import 'react-native-gesture-handler';
import React, { useEffect, useState } from 'react'
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack'
import { LoginScreen, HomeScreen, RegistrationScreen } from './src/screens'
import {decode, encode} from 'base-64'
if (!global.btoa) { global.btoa = encode }
if (!global.atob) { global.atob = decode }
const Stack = createStackNavigator();

export default function App() {

const [loading, setLoading] = useState(true)
const [user, setUser] = useState(null)

return (

<Stack.Navigator>
{ user ? (
<Stack.Screen name="Home">
{props => <HomeScreen {...props} extraData={user} />}
</Stack.Screen>
) : (
<>
<Stack.Screen name="Login" component={LoginScreen} />
<Stack.Screen name="Registration" component={RegistrationScreen} />
</>
)}
</Stack.Navigator>

);
}

登录.js

. . .
const onLoginPress = () => {
firebase
.auth()
.signInWithEmailAndPassword(email, password)
.then((response) => {
const uid = response.user.uid
const usersRef = firebase.firestore().collection('users')
usersRef
.doc(uid)
.get()
.then(firestoreDocument => {
if (!firestoreDocument.exists) {
alert("User does not exist anymore.")
return;
}
const user = firestoreDocument.data()
navigation.navigate('Home', {user})
})
.catch(error => {
alert(error)
});
})
.catch(error => {
alert(error)
})
}
. . .

注册.js

  const onRegisterPress = () => {
    if (password !== confirmPassword) {
        alert("Passwords don't match.")
        return
    }
    firebase
        .auth()
        .createUserWithEmailAndPassword(email, password)
        .then((response) => {
            const uid = response.user.uid
            const data = {
                id: uid,
                email,

            

fullName,
            };
            const usersRef = firebase.firestore().collection('users')
            usersRef
                .doc(uid)
                .set(data)
                .then(() => {
                    navigation.navigate('Home', {user: data})
                })
                .catch((error) => {
                    alert(error)
                });
        })
        .catch((error) => {
            alert(error)
    });
}

错误是由 App.js 中的这一行引起的:

{ user ? (
<Stack.Screen name="Home">
`   `{props => <HomeScreen {...props} extraData={user} />}
</Stack.Screen>
) : (

**使用这些版本:“@react-navigation/native”:“^5.8.10”,“@react-navigation/stack”:“^5.12.7”,**我更新了“@react-navigation/stack”到 5.12.8 仍然相同的错误

before it throws the error it gives me this warning
"Setting a timer for a long period of time"**

标签: reactjsstackreact-native-androidreact-navigation

解决方案


当您尝试导航到堆栈导航器中不存在的屏幕时会显示此错误,我看到您正在尝试根据用户数据进行导航,而此用户值仍未更新null,因此主屏幕不会被添加到堆栈中,react-navigation 会显示一个错误。

我建议我们先对代码进行排序,然后分离AppNavigation成一个新的 JSX 脚本,如下所示:

import 'react-native-gesture-handler';
import React, { useEffect, useState } from 'react'
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack'
import { LoginScreen, HomeScreen, RegistrationScreen } from './src/screens'
import {decode, encode} from 'base-64'
if (!global.btoa) { global.btoa = encode }
if (!global.atob) { global.atob = decode }
const Stack = createStackNavigator();

export default function App() {

return (
  <AppNavigation/>
);
}

然后在 AppNavigation 里面:

  • 由于您使用的是 firebase,因此无需将用户数据传递到下一个屏幕,您可以使用它fire.auth().currentUser来获取当前的用户数据。
  • 还用于fire.auth().onAuthStateChanged侦听用户状态更改,因此每当用户登录时,它应该立即更新并用登录屏幕替换登录注册屏幕,而无需在onLoginPress内部调用navigation.navigate('Home', {user})
  • 最后一件事,您必须创建一个闪屏以显示给用户,直到验证您的用户是否登录。
import React, {Component} from 'react';
import { LoginScreen, HomeScreen, RegistrationScreen } from '../src/screens'
import { createStackNavigator } from '@react-navigation/stack';
import { NavigationContainer } from '@react-navigation/native';
import fire from '../config/Fire';
import Splash from '../components/common/Splash';


const Stack = createStackNavigator();

class AppNavigation extends Component {

  constructor(props){
    super(props);
    this.state = {
      loggedIn : null,
    }
  }

  componentDidMount(){
    this.authListner();
  }

  componentWillUnmount(){
    // unsubscribe
    this.setState({
      loggedIn:null,
    })
  }

  authListner(){
    fire.auth().onAuthStateChanged(user => {
      //console.log(user)
      if (!user){
        this.setState({
          loggedIn:false,
        })
      } else if (user){
        this.setState({
          loggedIn:true,
        }) 
      }    
    }
    )
  }

  render = () => {
    if (this.state.loggedIn == null) {
      // We haven't finished checking for the token yet
      return <Splash />;
    }

      return (
        <NavigationContainer>
          <Stack.Navigator initialRouteName="Login">
            {
              this.state.loggedIn == false ? (
                <>
                  <Stack.Screen name="Login" component={LoginScreen} />
                  <Stack.Screen name="Registration" component={RegistrationScreen} />

                </>
              ) : 
                <>
                  <Stack.Screen name="Home" component={HomeScreen}/>
                </>
           }

          </Stack.Navigator>
        </NavigationContainer>
      )
}


export default AppNavigation;

推荐阅读