Pre-rendered static pages are great for performance, however, they can reduce the quality of our user's experience. Content may feel less relevant and engaging if it doesn't change based on the information our user has already the app.
We will use the state of our user to dynamically change the call to action button for each plan. If we don't have a user, we want them to create an account; if we have a user but they are not subscribed, we want them to subscribe; and if we have a user that is subscribed, we want to give them the option to manage their subscription.
Additionally, we implement a loading state for our useUser
hook, which can be used to determine whether we are waiting for our auth.users
data to be enriched with the columns from our profile
table.
By using the isLoading
state, our pricing page can delay the rendering of the call to action button until we have the necessary state to display the correct one.
Instructor: [0:00] On our Pricing page, we have a list of each of our products, but no call-to-action to actually subscribe. Let's add that now. Let's add a button that says, Subscribe, for each of our plans.
[0:10] This looks good, but it only really makes sense if we have a user. We can't really subscribe a user who hasn't created an account yet. We want this to be a separate call-to-action to create an account if we don't have a user. Let's bring in our useUser hook, and call it to get our user.
[0:29] Now, we want to create a few different states. We want to show the Subscribe button only if we have a user and they are not yet subscribed. We want to show the Create Account button if we don't have a user at all. We want to show a Manage Subscription button if we have a user and that user is subscribed. Let's implement those three states. If we want to create an account, this is just basically the same as logging in because we're using GitHub.
[1:07] We can just bring in that function from our useUser hook and call that function onClick. We can click that button to log in our user. We see the text Manage Subscription and that's because our user profiles is subscribed column is set to true.
[1:23] If we refresh, we see the text Subscribe for a split second before it changes to Manage Subscription. That's because back up in our useUser hook, we're initially setting our user to be equal to our auth.user before we enrich it with that profile data that contains the isSubscribed column.
[1:41] Let's create a new variable to keep a track of whether our user is still loading extra data. Let's initialize this to true. Then after we've set the user with their additional profile information, let's call set is loading and set it to false.
[1:56] Let's then expose this as a value from our provider and destructure it in our pricing page. We can wrap all of these buttons in a div that only displays if isLoading is set to false. When we refresh, we only see the correct option pop in once we have enough data to actually display it.
[2:16] If we unsubscribe our user and refresh our page, we see our subscribe state. If we were to log out and navigate back to our pricing page, we see create account. Each of our three states is working correctly.
If you put
setIsLoading(false)
ingetUserProfile
function, thenisLoading
will always be set to false untilgetUserProfile
is called.getUserProfile
is called only if there is a session.In some cases, it never gets called.
Instead of writing
setIsLoading(false)
in thegetUserProfile
function, I would set it outside when it's first get called:This way we make sure it's always set to false right after
getUserProfile
gets called.Hope that makes sense 😊 Happy coding!