Give Feedback While Logging In
It’s important that we give the user some feedback while we are logging them in. So they get the sense that the app is still working, as opposed to being unresponsive.
Use an isLoading Flag
To do this we are going to add an isLoading
flag to the state of our src/containers/Login.js
. Add the following to the top of our Login
function component.
const [isLoading, setIsLoading] = useState(false);
And we’ll update it while we are logging in. So our handleSubmit
function now looks like so:
async function handleSubmit(event) {
event.preventDefault();
setIsLoading(true);
try {
await Auth.signIn(email, password);
props.userHasAuthenticated(true);
props.history.push("/");
} catch (e) {
alert(e.message);
setIsLoading(false);
}
}
Create a Loader Button
Now to reflect the state change in our button we are going to render it differently based on the isLoading
flag. But we are going to need this piece of code in a lot of different places. So it makes sense that we create a reusable component out of it.
Create a new file and add the following in src/components/LoaderButton.js
.
import React from "react";
import { Button, Glyphicon } from "react-bootstrap";
import "./LoaderButton.css";
export default function LoaderButton({
isLoading,
className = "",
disabled = false,
...props
}) {
return (
<Button
className={`LoaderButton ${className}`}
disabled={disabled || isLoading}
{...props}
>
{isLoading && <Glyphicon glyph="refresh" className="spinning" />}
{props.children}
</Button>
);
}
This is a really simple component that takes an isLoading
flag and the text that the button displays in the two states (the default state and the loading state). The disabled
prop is a result of what we have currently in our Login
button. And we ensure that the button is disabled when isLoading
is true
. This makes it so that the user can’t click it while we are in the process of logging them in.
And let’s add a couple of styles to animate our loading icon.
Add the following to src/components/LoaderButton.css
.
.LoaderButton .spinning.glyphicon {
margin-right: 7px;
top: 2px;
animation: spin 1s infinite linear;
}
@keyframes spin {
from { transform: scale(1) rotate(0deg); }
to { transform: scale(1) rotate(360deg); }
}
This spins the refresh Glyphicon infinitely with each spin taking a second. And by adding these styles as a part of the LoaderButton
we keep them self contained within the component.
Render Using the isLoading Flag
Now we can use our new component in our Login
container.
In src/containers/Login.js
find the <Button>
component in the return
statement.
<Button block bsSize="large" disabled={!validateForm()} type="submit">
Login
</Button>
And replace it with this.
<LoaderButton
block
type="submit"
bsSize="large"
isLoading={isLoading}
disabled={!validateForm()}
>
Login
</LoaderButton>
Also, import the LoaderButton
in the header. And remove the reference to the Button
component.
import { FormGroup, FormControl, ControlLabel } from "react-bootstrap";
import LoaderButton from "../components/LoaderButton";
And now when we switch over to the browser and try logging in, you should see the intermediate state before the login completes.
If you would like to add Forgot Password functionality for your users, you can refer to our Extra Credit series of chapters on user management.
Next let’s implement the sign up process for our app.
For help and discussion
Comments on this chapterIf you liked this post, please subscribe to our newsletter, give us a star on GitHub, and follow us on Twitter.