How to Build a Login/Register App with the MERN Stack (Part 5): Connecting Frontend to Backend

In the previous part of this tutorial, How to Build a Login/Register App with the MERN Stack (Part 4): Setting Up Frontend Routes, we created our Frontend pages with React. In this part, we will connect Frontend to Backend using React’s Context API.

Creating Users Context

Basic Component

First, let’s create a contexts folder in client/src, and create a Users.js file inside it. After that, let’s create a regular Class Component called UsersContextProvider.

UsersContextProvider component - How to build a login/register app with the MERN stack

To be able to complete this component and write its render lifecycle method, we need to create a context first.

userscontextprovider basics complete - How to build a login/register app with the MERN stackAs you can see, we created a context on line 3 using React.createContext(). Then, we return a provider of that context in the render method, passing the value of this.state to the children of this provider. We also render the children components that get passed to this provider, as shown on line 21, so that we can wrap other components with this component. Finally, we export the context itself along with the provider component.

To actually make this context useful, we need to define the methods we mentioned on lines 12, 13, and 14. But before we go ahead and implement them, let’s define a constant called API_URL to make it easier to mention the API URL any where in this context’s code.

const API_URL =
  process.env.NODE_ENV === 'production'
    ? 'PRODUCTION_URL'
    : 'http://localhost:5000';

NOTE: We will replace that ‘PRODUCTION_URL‘ placeholder later.

The logUserIn Method

logUserIn method - How to build a login/register app with the MERN stack

This method is supposed to return an object containing title and text properties. These properties will be used alongside with sweetalert-react to show nice alerts to the user. So, first, we send a POST request to the login endpoint of the API. We specify the Content-Type to be application/json so that the server can parse data correctly. We send Cookies along with this request, so that the server can use our session data, by setting the credentials option to 'include'. And we also send the username and password as body of this request. On line 14, we get out data from the response we got back. We do some basic processing, based on how we wrote the API endpoints, for the status code we got. If every thing went well, we update the state to have isLoggedIn set to true, and store user info we got back.

The registerUser Method

registerUser method - How to build a login/register app with the MERN stack

This method is also supposed to return a similar object to that returned by logUserIn method. First, we do very basic validation for the data, you can go beyond this if you want. If the data is OK, we send them via a POST request to the register endpoint of the API. Finally, we process the status code we get from that request and set different values for title and text based on each condition.

The logUserOut Method

logUserOut method - How to build a login/register app with the MERN stack

Although this method is very simple, it is extremely important to send cookies along with the request to the logout endpoint of the API, so that the server can destroy the session of the client sending that request.

The componentDidMount Lifecycle Method

We will use this lifecycle method to make sure users can’t just open a new tab and go to the login or register page when they are already logged in. We make a GET request to the currentUser endpoint of the API, and update the state with the received data.

Using Users Context

To make components in our app able to use data in Users context, we need to import UsersContextProvider component into client/index.js. And then wrap the App component with it.

Finishing Up Pages Components

Creating NavBar Component

In your src/components folder, create a NavBar folder and put the following lines in a NavBar.js file inside it.

NavBar component JSX

As you can see, this is a very basic component that renders a NavBar with a button in it. To be able to use the logUserOut method from the Users context, we first need to import the context. Then, assign the UsersContext to a static class field called contextType. And now, we can access the data provided by this context through this.context. So, we set the onClick prop of the button to be this.context.logUserOut. Easy! Right?

And this is NavBar.css:

Navbar component CSS

Re-creating Home Page

Now we have Users context, let’s re-create the Home page.

Home page component - JSX

At first, we do the very basic context setup. Then, in the render method we check if the user is not logged in, if they are not, we redirect them to the login page. Otherwise, we return the NavBar and a welcome message with the username in it.

And here is Home.css:

Home page component - CSS

Finishing Up Login Page

Alright, let’s finish up the parts of login page component that depend on Users context.

First, add these import lines to the top of your Login.js.

import { UsersContext } from '../../contexts/Users';
import { Redirect } from 'react-router-dom';
import SweetAlert from 'sweetalert-react';
import 'sweetalert/dist/sweetalert.css';

Then, declare contextType as usual, and add this object to the state.

alert: {
  showAlert: false,
  title: '',
  text: '',
}

Afterwards, change the handleFormSubmit method to be:

Login.js - handleFormSubmit method

We get the username and password from the state, pass them to the logUserIn function we get from the context, and update the state with what we get back.

Finally, we need to update the render method as shown below:

Login.js - render method

We redirect the user if they are logged in to the home page on line 3. We also render the SweetAlert component as shown on lines 10-15. You can read sweetalert-react‘s documentation to know how to use it.

Finishing Up Register page

We do the exact same thing we did for Login.js to Register.js, except for the handleFormSubmit method.

Register page - handleFormSubmit method

Conclusion

First, we learnt about the Context API and created our Users context. Then, we added some methods to it to make it easier to connect Frontend to Backend. Finally, we completed working on the pages and components that needed the Users context. In the next part of this tutorial, we will finally deploy this app to Heroku.

NOTE: You can find all parts of this tutorial here and code here.

3
0

Related Posts