To manage state in React you have many different options, but combining Supabase with React Context is a powerful way to keep your app's state in sync with your backend. In this post, I'll show you the code snipped which I have used in my project to manage the state of the user subscription status, but you can adapt it to manage any state in your app.
We'll create a ProfileContext
that can hold any piece of state you want to manage. In this example, we'll track if a user is subscribed, but you can change it to anything else.
Here's the full code:
1import {2 createContext,3 useState,4 useMemo,5 ReactNode,6 useContext,7 useCallback,8 useEffect,9} from 'react';10import { useSupabaseClient, useUser } from '@supabase/auth-helpers-react';11import toast from 'react-hot-toast';12
13interface ProfileContextProps {14 isSubscribed: boolean;15}16
17interface ProfileProviderProps {18 children: ReactNode;19}20
21const ProfileContext = createContext<ProfileContextProps>({22 isSubscribed: false,23});24
25const ProfileProvider = ({ children }: ProfileProviderProps) => {26 const supabase = useSupabaseClient();27 const user = useUser();28
29 const [isSubscribed, setIsSubscribed] = useState<boolean>(false);30
31 const fetchProfile = useCallback(async () => {32 try {33 let { data, error } = await supabase34 .from('profiles')35 .select('isSubscribed')36 .eq('id', user?.id)37 .single();38
39 if (error) throw error;40
41 if (data) {42 setIsSubscribed(data.isSubscribed);43 }44 } catch (error) {45 toast('An error occurred. Please try again later.');46 console.log(error);47 }48 }, [supabase, user]);49
50 useEffect(() => {51 if (user) {52 fetchProfile();53 }54 }, [fetchProfile, user]);55
56 return (57 <ProfileContext.Provider58 value={useMemo(59 () => ({60 isSubscribed,61 }),62 [isSubscribed]63 )}64 >65 {children}66 </ProfileContext.Provider>67 );68};69
70const useProfileContext = () => {71 return useContext(ProfileContext);72};73
74export { useProfileContext, ProfileContext, ProfileProvider };
So what happens here? Let's break it down:
ProfileContext
with a default value for isSubscribed
.useState
to manage isSubscribed
.fetchProfile
uses Supabase to get the subscription status from the profiles table.useEffect
calls fetchProfile
whenever the user changes.useMemo
ensures the context value updates only when isSubscribed
changes.useProfileContext
makes it easy to access the context in your components.Note #1: This code assumes you have a
profiles
table in your Supabase database with a columnisSubscribed
. You can adjust it to fit your schema.
Note #2:
react-hot-toast
is used for displaying error messages. You can replace it with any other toast library or error handling mechanism.
Wrap your components with ProfileProvider
and use the useProfileContext
hook to get the context values.
1import { ProfileProvider, useProfileContext } from './profileContext';2
3const App = () => {4 return (5 <ProfileProvider>6 <MainComponent />7 </ProfileProvider>8 );9};10
11const MainComponent = () => {12 const { isSubscribed } = useProfileContext();13
14 return (15 <div>16 {isSubscribed ? <PremiumContent /> : <StandardContent />}17 </div>18 );19};
Combining React Context with Supabase is a great way to manage state in your app. This example shows how to keep your app's state in sync with your backend easily. Whether it's subscription status or any other piece of state, this approach helps you maintain clean and efficient code.
Got questions or comments? Feel free to leave them below.
Sign up to get updates when I write something new. No spam ever.
Subscribe to my Newsletter