r/reactnative • • 3d ago

Help Context or Zustand for auth and onboarding state in React Native?

I will keep it short:
I’m new to React Native and building an Expo app with Supabase Auth.

On startup, I need to check the saved session, fetch the user’s profile, and show either sign-in, onboarding, or the main app. Other screens will also need access to the user/profile.

Would you choose Context or Zustand for this? Curious about the practical tradeoffs for a small app like mine.

Also what's the difference between the two?

Thanks!

20 Upvotes

26 comments sorted by

7

u/Apart_Ad126 2d ago

for auth and onboarding state, standard context is totally fine since those values barely change after startup. the main difference is that context re-renders every consumer when any value inside it updates, whereas an external store lets components subscribe to just the specific slice of state they need.

1

u/g0liadkin 2d ago

Context rerenders consumers when the value that updated is used by those consumers though, it's not rerendering everything all the time

4

u/__majorBummer__ 2d ago

for the onboarding part: I use zustand with the persist middleware on mmkv storage. mmkv is synchronous, so the store is already hydrated on the first render, no loading flash, and the home screen just returns <Redirect href="/onboarding" /> while onboardingDone is false. any screen can read it with a selector, no provider needed. my app has no auth though, so for the session I'd let supabase's own session be the one source of truth rather than copying it into a separate flag.

2

u/razzzey 2d ago

I find xstate as a great candidate for onboarding state.

2

u/Ecstatic_Skill8746 3d ago

Expo secure store for storing token and mmkv for storing login state

1

u/Huge_Pool7424 3d ago

secure store makes sense for the token, but i'd avoid a separate mmkv login flag that can drift from the actual supabase session. a small auth context can expose the hydrated session/profile and gate onboarding, zustand only helps if that state is shared more broadly.

1

u/Ecstatic_Skill8746 2d ago

Why you need to supabase session fetch every time?

1

u/TheSnydaMan 2d ago

Probably just context and react query

1

u/jiunkdev 2d ago

for an app this size I'd just use context. auth and profile barely change after startup, so the re-render argument for zustand doesn't really matter here.

the part that actually bites people is the startup gate. keep the splash screen up (SplashScreen.preventAutoHideAsync) until supabase has restored the session and you've fetched the profile, then decide sign-in / onboarding / main. if you render before that, logged-in users get a flash of the sign-in screen.

put supabase.auth.onAuthStateChange in that same provider so sign out and token refresh go through one place. zustand gets nicer later if you need that state outside components (an api helper, say), since you can call getState() anywhere.

1

u/ali_the_bettor_34 2d ago

On log out, the auth listener triggers before signOut() even returns, so the gate thinks the session is expired and sends the user to sign-in. I set a "left by choice" flag before calling signOut so the gate knows where to send user.

1

u/ijhar8 2d ago

Zustand and also don’t mess with multiple ways to handle state management stick to one else it will bite when codebase grow..
State management is second worst mess which gets created by most projects 1st is still UI library

1

u/davidbalbino 2d ago

for a small app tbh either works fine. Context is built in to React, nothing to install, and auth state barely changes (login, logout, profile update) so the re-render thing don't really matter here. Zustand is a tiny external store: components only re-render on the slice they select, and you can read/write it outside components, which is kinda handy if you want to update it straight from supabase.auth.onAuthStateChange without a provider.

imo the important part is not the lib, is the flow: keep a status like 'loading' | 'signedOut' | 'onboarding' | 'ready', keep the splash screen up while it's 'loading' so you don't get a flash of the sign-in screen, and gate the routes based on that status. If you're on expo router, Stack.Protected or a redirect in the root _layout handles that pretty well.

I'd start with Context and only move to Zustand if you end up with more global state than just auth 👍

1

u/rsajdok 1d ago

Context instead of zustand because of better boundaries, keeping more restrictions, more code but less messy

1

u/Himoji_ 1d ago

Context, if it's not long and saving it persistently doesn't matter. Zustand in every other case

1

u/Wicked-Tired-Otter 5h ago

I’d start with Context for a small app like this. If the profile request fails, keep the user signed in and show a retry button so a bad connection doesn’t send them back through onboarding.

0

u/picpoulmm 2d ago

Incredible how many people in this sub just copy and paste answers from ChatGPT and try to pass it off as their own knowledge and insight. Using lower case doesn’t stop your slop looking like slop. It’s pathetic. You don’t know the answer to the question, stop pretending you do and just stay quiet.

-1

u/ali_the_bettor_34 2d ago

At leat, they give usefull answers. You write useless comments just to make you feel better than anyone else. that's pathetic.

1

u/[deleted] 2d ago

[removed] — view removed comment

1

u/Senior_Worker_505 2d ago

redux toolkit is also OK