nandorojo / solito

🧍‍♂️ React Native + Next.js, unified.
https://solito.dev
MIT License
3.54k stars 181 forks source link

Error after calling replace (The 'navigation' object hasn't been initialized yet) #192

Closed david-roeger closed 1 year ago

david-roeger commented 2 years ago

Hi,

I want to implement Authentification and thus redirect the users from the home screen if they are not logged in. Therefore I show a loading screen and check in an useEffect if the user is present and if not i want to redirect them to the login screen:

const {user, isLoading} = useUser()

useEffect(()=> {
  if (!isLoading && !user) {
     replace('/login')
  }
}, [replace, user, isLoading]);

if(isLoading) {
  return <P>Loading...</P>
}

<View>
...
</View>

Unfortunately this throws an Error on iOS and Android concerning react-navigation

Error

Console Error

Stacktrace

The 'navigation' object hasn't been initialized yet. This might happen if you don't have a navigator mounted, or if the navigator hasn't finished mounting. See https://reactnavigation.org/docs/navigating-without-navigation-prop#handling-initialization for more details. 
HomeScreen@http://10.11.11.126:19000/index.bundle?platform=ios&dev=true&hot=false:131545:32
StaticContainer@http://10.11.11.126:19000/index.bundle?platform=ios&dev=true&hot=false:126644:17
EnsureSingleNavigator@http://10.11.11.126:19000/index.bundle?platform=ios&dev=true&hot=false:123006:24
SceneView@http://10.11.11.126:19000/index.bundle?platform=ios&dev=true&hot=false:126549:22
RCTView
View
DebugContainer@http://10.11.11.126:19000/index.bundle?platform=ios&dev=true&hot=false:131268:36
MaybeNestedStack@http://10.11.11.126:19000/index.bundle?platform=ios&dev=true&hot=false:128383:23
RNSScreen
AnimatedComponent@http://10.11.11.126:19000/index.bundle?platform=ios&dev=true&hot=false:73139:38
AnimatedComponentWrapper
MaybeFreeze@http://10.11.11.126:19000/index.bundle?platform=ios&dev=true&hot=false:130614:23
Screen@http://10.11.11.126:19000/index.bundle?platform=ios&dev=true&hot=false:130659:36
SceneView@http://10.11.11.126:19000/index.bundle?platform=ios&dev=true&hot=false:128429:27
RNSScreenStack
ScreenStack
NativeStackViewInner@http://10.11.11.126:19000/index.bundle?platform=ios&dev=true&hot=false:128569:22
RNCSafeAreaProvider
SafeAreaProvider@http://10.11.11.126:19000/index.bundle?platform=ios&dev=true&hot=false:129301:24
SafeAreaProviderCompat@http://10.11.11.126:19000/index.bundle?platform=ios&dev=true&hot=false:130327:25
NativeStackView
NativeStackNavigator@http://10.11.11.126:19000/index.bundle?platform=ios&dev=true&hot=false:120695:18
NativeNavigation
BreakpointIndexProvider@http://10.11.11.126:19000/index.bundle?platform=ios&dev=true&hot=false:132699:25
DripsyProvider@http://10.11.11.126:19000/index.bundle?platform=ios&dev=true&hot=false:134313:30
Dripsy@http://10.11.11.126:19000/index.bundle?platform=ios&dev=true&hot=false:186371:24
EnsureSingleNavigator@http://10.11.11.126:19000/index.bundle?platform=ios&dev=true&hot=false:123006:24
BaseNavigationContainer@http://10.11.11.126:19000/index.bundle?platform=ios&dev=true&hot=false:121350:28
ThemeProvider@http://10.11.11.126:19000/index.bundle?platform=ios&dev=true&hot=false:127719:21
NavigationContainerInner@http://10.11.11.126:19000/index.bundle?platform=ios&dev=true&hot=false:127593:26
NavigationProvider@http://10.11.11.126:19000/index.bundle?platform=ios&dev=true&hot=false:186408:24
Provider@http://10.11.11.126:19000/index.bundle?platform=ios&dev=true&hot=false:186338:24
App
ExpoRoot@http://10.11.11.126:19000/index.bundle?platform=ios&dev=true&hot=false:120355:22
RCTView
View
DevAppContainer@http://10.11.11.126:19000/index.bundle?platform=ios&dev=true&hot=false:120042:36
RCTView
View
AppContainer@http://10.11.11.126:19000/index.bundle?platform=ios&dev=true&hot=false:80762:36
main(RootComponent)@http://10.11.11.126:19000/index.bundle?platform=ios&dev=true&hot=false:87169:28

The Error references https://reactnavigation.org/docs/navigating-without-navigation-prop#handling-initialization. Maybe this issue can be solved by additionally returning an isReady Prop from useRouter?

Reproduction

https://github.com/david-roeger/solito-redirect-error

I cloned the starter repo and added the following to home/screen.tsx

  const {replace} = useRouter()

  useEffect(()=> {
    replace('/user/hello')
  }, [replace])

Thanks in advance!

nandorojo commented 2 years ago

I don't think your repo has the code you mentioned.

https://github.com/david-roeger/solito-redirect-error/blob/main/packages/app/features/home/screen.tsx

nandorojo commented 2 years ago

I want to implement Authentification and thus redirect the users from the home screen if they are not logged in.

I don't typically recommend this pattern. In my Next.js Conf talk on Oct 25, I outline a different way to approach this.

david-roeger commented 2 years ago

I don't think your repo has the code you mentioned.

I forgot to commit the changes. They are available now... Sorry for the inconvenience

I don't typically recommend this pattern. In my Next.js Conf talk on Oct 25, I outline a different way to approach this.

That's exciting to hear. Looking forward to your talk 🤩

nandorojo commented 1 year ago

Hey all, please see my latest talk on how to gate content for auth. Rather that using replace redirects, it uses conditional rendering. This is a better approach for React in my opinion. Hope it helps!

https://www.youtube.com/watch?v=H1gSWXA3qfw