Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
387 views
in Technique[技术] by (71.8m points)

javascript - Trouble accessing react navigation (v5) without the navigation prop / outside components

In my react native project, I have an authContext file to manage user signup and login.

Once a user has signed up (or logged in) successfully, I want the relevant function in the context file to redirect the user to a homepage ('TrackList'). Because the context sits outside the react navigation container, I have been following the v5 react navigation docs for 'Navigating without the navigation prop' which clearly states that "you may use this approach outside of your React components". Here is my implementation, which I will try to keep to a minimum for readability.

AuthContext file looks like this:

import React, { useState } from "react"
import trackerApi from "../api/tracker"

import * as RootNavigation from '../RootNavigation'

const AuthContext = React.createContext()

export const AuthProvider = ({ children }) => {

    const [token, setToken] = useState(null)//token from express server indicates user signed in
    const [errorMessage, setErrorMessage] = useState("")

    const signup = async ({ email, password }) => {
        try {
            //returns JSON Web Token JWT and update state
            const response = await trackerApi.post("/signup", { email, password })
            setToken(response.data.token)
        } catch (err) {
            setErrorMessage("Something went wrong with sign up")
        }
        //after successful signup we redirect  
        RootNavigation.navigate('TrackList')
    }

    const signIn = ...

    const signOut = ...

    return <AuthContext.Provider value={{ token, signup, signIn, signOut, errorMessage }}>
        {children}
    </AuthContext.Provider>
}

export default AuthContext

Then within my App.js I have:

import { NavigationContainer } from '@react-navigation/native';
import { navigationRef } from './RootNavigation';
import { AuthProvider } from "./src/context/AuthContext"
(...other relevant imports)

function TrackListFlow() {
  return (
    <Stack.Navigator initialRouteName="Signup">
     //**SCREEN I WANT TO REDIRECT TO: **
      <Stack.Screen name="TrackList" component={TrackListScreen} />
      <Stack.Screen name="TrackDetail" component={TrackDetailScreen} />
    </Stack.Navigator>
  )
}

function MainFlow() {
  return (
    <Tab.Navigator initialRouteName="TrackListFlow">
      <Tab.Screen name="TrackListFlow" component={TrackListFlow} />
      <Tab.Screen name="TrackCreate" component={TrackCreateScreen} />
      <Tab.Screen name="Account" component={AccountScreen} />
    </Tab.Navigator>
  )
}

function App() {
  return (
    <NavigationContainer ref={navigationRef}>
      <Stack.Navigator initialRouteName="LoginFlow" >
        <Stack.Screen name="LoginFlow" component={LoginFlow}/>
        <Stack.Screen name="MainFlow" component={MainFlow} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

The login process works, and when using buttons WITHIN the navigation container, the react navigation process works fine. However, I can't seem to navigate to the screen outside the navigation container (ie from authcontext). When I do, I get the following error:

The action 'NAVIGATE' with payload {"name":"TrackList"} was not handled by any navigator. Do you have a screen named 'TrackList'?

I must admit, that while I follow a lot of the react navigation docs and processes, I am a bit confused about this section so it's possible I'm taking the wrong approach entirely. Help appreciated! Thanks.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Just for curiosity, can you provide your RootNavigation file code?

But I think that your problem is that you don't have the "TrackListFlow" component in the "App" function return. Your "App" function should be like this:

function App() {
  return (
    <NavigationContainer ref={navigationRef}>
      <Stack.Navigator initialRouteName="LoginFlow" >
        <Stack.Screen name="LoginFlow" component={LoginFlow}/>
        <Stack.Screen name="MainFlow" component={MainFlow} />
        <Stack.Screen name="TrackListFlow" component={TrackListFlow} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

Try this code and give me your feedback :).


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...