Jack23
Jack23

Reputation: 1396

Navigation.navigate: was not handled by any navigator

I'm using navigation for the first time, I'm creating a form to signup an user.

Now after the user makes the signup I would to redirect with the Home page using the user data.

I have made in this way:

Registration.js

const onRegisterPress = () => {
    if (password !== confirmPassword){
        alert('Error passwords')
        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)
        //There:
        .then(() => {
            navigation.navigate("Home",{user: data})
        })
        .catch((error) => {
            alert(error)
        });
    })
    .catch((error) => {
        alert(error)
    })
}

App.js

return (
    <NavigationContainer>
   <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>
    </NavigationContainer>
  );
}

After the signup (that works), I Receive the error message:

The action 'NAVIGATE' with payload {"name":"Home","params": {"user":{"id":"myid","email":"myemail","fullName":"myfullname"}}}} was not handled by any navigator.

Do you have a screen named 'Home'?

How can I fix it?

Thank you

Upvotes: 0

Views: 884

Answers (3)

Valentin Briand
Valentin Briand

Reputation: 3693

You don't even need to navigate manually.
Assuming user in App.js gets updated when the user logs in, the authentication stack will be unmounted, and the Home stack will appear instead.

More info here if needed: https://reactnavigation.org/docs/auth-flow

Upvotes: 1

Thales Kenne
Thales Kenne

Reputation: 2932

You probably didn't import the navigation prop from react-navigation.

import {useNavigation} from 'react-navigation'

Then in component:

const registration = () => {
   const navigation = useNavigation();

  const onRegisterPress = () => {
    // handle your Auth here
    navigation.navigate('home');

  }


  return(...whateveryourJsxIs)
}

This is assuming you're using a functional component.

Upvotes: 0

Qrow Saki
Qrow Saki

Reputation: 1062

Edit

I have a feeling this is because you have two different navigators. React is probably looking for the Home screen inside the Auth navigator, and not finding it.

When you do

navigation.navigate("Home",{user: data})

It is from inside .createUserWithEmailAndPassword so the navigation object refers to the auth navigator.

What you can do instead of a direct "navigation.navigate" is at the root of you code, have a if else.

If logged-in return Navigator-with-home, else return Auth Navigator.

Have a loggedin setState that is controlled by firebase.auth().onAuthStateChanged. Everytime the user is logged out, setState to false, everytime logged in, setState to true. Now, you are dynamically switching navigators. React won't get confused.

Example snippet:

    firebase.auth().onAuthStateChanged((user) => {
      if (user) {
        this.setState({loggedIn: true});
      } else {
        this.setState({loggedIn: false});
      }
    });

Previous answer:

Why didn't you put a component prop on the Home screen like you did for the others? That's how react finds which screen to serve, not by the name "Home", but by the component Home.

You should have:

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

If you want params, you can do:

<Stack.Screen name="Home" component = {HomeScreen} initialParams={{extraData: user}}>

(I'm not sure if you need brackets around {user}. Try with and without.) You can access extraData with route.params.extraData. Route is passed automatically along with navigation as a prop whenever you navigate to a screen.

So for class-based components, you can access it with this.props.route.params.extraData, and for functional-based, you can do props.route.params.extraData or access it directly route.params.extraData if you destructured it.

Upvotes: 2

Related Questions