Final UX Refinements for Authentication Workflow
Great job in making it through that authentication section. This is the longest section of the entire course and you learned a lot about the fundamentals of React, especially as they relate to authentication which is a feature you're probably going to have to build into any application that you develop over the years.
Guide Tasks
  • Read Tutorial
  • Watch Guide Video
Video locked
This video is viewable to users with a Bottega Bootcamp license

So in this last guide, we're going to add a few "polish" items that I think any advanced course should include.

So let's walk through what those are. First and foremost, let's remove this null call here.

Removing "null"

medium

We're never going to have a current user on this screen so it doesn't make sense to keep that. So let's start off by just removing "currentUser" and then remove where that is called.

Removing CurrentUser

medium

You can either search for it or just come down to where we're printing that out. So we can get rid of that entire view.

Removing Entire View

medium

Hit Save and that's removed. So that is looking nice and so now we don't have any debugging code in our application, now the next thing is we have a little bit of a user experience glitch occurring here with our registration process. You may have already noticed it, so if you click on "Register" and type this out, so I'm going to do "46202@devcamp.com".

If I click "Register", watch what happens to this button.

medium

Did you notice how it switches back and says "Register" for a split second?

Before

medium

After

medium

I think that we can do better than that. I think that we can fix that so it just says is submitting and it does that all the way up until the user's redirected. So let's click "Sign Out" here and scroll up and see why that is occurring. So if you go to "handleRegistration", the reason why that's occurring is because in this code right here, we're checking to see if the user is authenticated. If they are, then we're passing them to login.

Now the reason for this error is because we are setting "isSubmitting" to false down here outside of the conditional.

handleRegistration

medium

So what that means is that this is always going to get called no matter what. If you want to think of the flow of it, what's happening is the user is registering here, so they're typing in their information, when you click on "Register", what's happening is it's starting this "handleLogin" process after it's created that account and then while that's occurring, it is setting this to false which is why that "Register" is swapped back. So the way that we can fix that, because we want to make sure that "setIsSubmitting" false it does occur if an error occurs, we can simply add that right inside of this conditional and that way we know that that is going to work.

handleRegistration

if (response.data.memipedia_user) {
          handleLogin();
        } else {
          setIsSubmitting(false);
          alert(
            `Error creating account: ${formatErrors(response.data.errors)}`
  );
}

We already have all of that in place up here and we're also going to address another issue with that.

medium

So this is all, if this is a little bit kinda confusing or it's kinda hazy in how you're thinking about it, this all has to deal with asynchronous behavior and the reason for that is because each one of these tasks could take any amount of time, it's a variable amount of time. So because of that, what that means is right here, we need to control the steps and control the action triggers as we're building this out because we don't know how long it's going to take to check the server to see if a user is logged in or how long it's going to take for a user to be registered. Those are things you just always have to kind keep in mind. So I'm going to hit Save here and let's see if this works. So here I'm going to type another user 46203 and oh, you know what? I need to make sure I'm on the registration component, there we go. And type a password, hit Register now and you'll see that that worked.

Output

medium

So that is fixed and that's all working nicely. So that bug is fixed, I'm going to hit" Refresh" here and it's not working for me so I'm going to open up the simulator again, and let's talk about the next little bug we're going to fix and then at the very end we're going to add a fun feature. So we'll mix in that at the end because there's something that I think you'll enjoy building out, I know I do. Okay, so what's the next bug? Let's see right here, if I type in this user and I click Login, do you see this little warning down here?

Output warning

medium

We haven't talked about that much yet because I wanted you to focus on what we're building but now is a good time to see what this is. So this is something that would not be shown in a published application. So this wouldn't pop up if this app was on the App Store. This is just something for you as you're developing it. So if you click on it, you'll see it pops up and it gives a little bit of a description.

Description

small

Sometimes these warnings are not really the best, they don't really give you all of the details that you need, it doesn't always point to a specific line of code to tell you, hey, go fix this. So what it's telling us is it can't perform a "React state update on an unmounted component", and then it goes on to say this is a no-op which essentially means this isn't going to crash the application but it probably means that there is a memory leak or there's something that needs to be addressed. So we are going to address that now.

First "Minimize"

medium

So I'm going to hit "Dismiss "and let's sign out.

hit "Dismissed"

medium

You have to hit "Refresh" here because once I've clicked "Dismiss" on a warning, it won't show it again until you've hit "Refresh". So let's see what the issue is. So I'm going to come up, this is occurring inside of this component, inside of this "handleLogin" function.

handleLogin

medium

So this is something, what I'm going to walk through is something that it's going to take you practice to understand what is really happening here so you can debug this in your own applications so I'm going to talk through how I personally would look at it. It said the warning said that essentially something is happening on an unmounted component. What it means is that we're calling a function or some process is running on a component that has been unmounted which means that component's done with. In this case, in our case, what it means is we are trying to run a process on the "AuthScreen" component even after we've redirected the user.

AuthScreen Component

medium

So hopefully that kinda makes sense on what that means, and the fix in this case also has to deal just like our last little bug, has to deal with this "setIsSubmitting(false)", and it's almost the identical situation..

setIsSubmitting

medium

So right here, we're saying if there's a jwt token, I want you to do these processes, I want you to set the token, I want you to populate the user, then I want you to redirect the user. If not, show this error. So what's happening though is no matter what happens with that jwt, this "setIsSubmitting(false)" is always going to run, and in this case where the user is authenticated, that "setIsSubmitting" is going to be called even when the user's been redirected which means the way React Native works is when that occurs, when a user is redirected, it wraps up this component and it throws it away. It says we don't need this anymore, it removes it from memory and it does all of that for performance. But we're saying, hey, I'm still trying to call this IsSubmitting method on it, and so that's what that warning is. The way to fix this is to just move this into these blocks.

handleLogin

if (response.data.jwt) {
          await SecureStore.setItemAsync(
            "memipedia_secure_token",
            response.data.jwt
          );
          getUser();
          setIsSubmitting(false);
          props.navigation.navigate("Feed");
        } else {
          setIsSubmitting(false);
          alert(
            "It looks like you typed in the wrong email or password, please try again"
          );
        }

So I'm going to have it so this runs right after we get the user and then right before we show the alert if the user is not authenticated. So let's hit Save and let's come test this out. So "reactnative@devcamp.com", "password", "Login" and you can see we don't have that warning anymore. That is working nicely.

Output

medium

Okay, so onto the last thing. This is a fun one right here. So if you noticed, when you're typing, whether you're doing this on your phone or if you're doing it in the simulator, it would be nice and you've probably seen this in a lot of other applications, for me to be able to do something like type this email address and then come and type the "password" and then just press the "Return" key, and that's if I'm on the simulator here or to press the "Return" key on the phone if you have that as your device, and I'd want that for the registration component and the login component. So how can we do that? Well if you look at the documentation for TextInput, you'll see that there is a prop that you can pass. So there is a prop that is called "onSubmitEditing" and so it's not exactly the best name prop, I don't really think because I think that it doesn't really say exactly what it's doing but what it essentially means is when you're done editing which means when you're done typing, I want you to have access to perform this task which in this case a better name for it I think would be something like "onReturnPressed" but that's not a component. I didn't write the language or the framework so it can't do that. So they call it "onSubmitEditing".

onSubmitEditing example

medium

It's the same thing as essentially saying when the users hit the "Return" key and that's all it is. So the way to do this is to just be able to say "handleSubmit".

onSubmitEditing

medium

So what's happening here is we are not putting this on the email form tag, we're only doing it for the "TextInput" for the password because that's when we want this to trigger. So when we hit "Return", it's going to then run that process. So it's going to be the same as a user pressing the "Login" button. So let's test this out. So I'm going to say "reactnative@devcamp.com", type it out and now instead of hitting "Login", I'm just going to hit "Return".

Hitting return "Key"

medium

Everything works just like we would expect.

Output

medium

So great job if you went through that, you now have a really nice authentication system that is working great and you've learned a lot about React along the way. With all of this built out, in the next section, we are going to start building out our feed.

Resources