DEV Community

Cover image for Calling and Consuming APIs with Mantine in ReactJS #3
Sam Preston
Sam Preston

Posted on • Edited on

Calling and Consuming APIs with Mantine in ReactJS #3

Intro

Welcome back to Part 3 of the series where I build a full frontend application using the new React Component Library Mantine. Our starting point is:

Part 3 Starting Point

If you want to know how we got this far please check out Part 1 and work your way through to here!

Part 1 - Using an API to generate users

Today we'll be building a window at the bottom of the Navbar component to display the user and any details such as username or email.

First we have to have a userbase, but wait...we don't have any. This is where Random User Generator comes in! Using the Axios module we can request a user by querying https://randomuser.me/api/.

To begin we'll modify our current project structure and add a directory called api, and within it create User.ts.

Project Structure

First we need to install the Axios module into our project, this is done in the terminal with npm install axios. From here we can import it into our User.ts file.

Now we can create an exported asynchronous function called fetchRandomUser:

import axios from 'axios'

export async function fetchRandomUser() {

}
Enter fullscreen mode Exit fullscreen mode

We want this function to return the result of the API call from https://randomuser.me/api/:

export async function fetchRandomUser() {
  return await axios.get('https://randomuser.me/api/')
}
Enter fullscreen mode Exit fullscreen mode

However, we need to add steps for what we want to do with the data which is returned. For this we'll use . notation:

export async function fetchRandomUser() {
  return await axios.get('https://randomuser.me/api/')
    .then((response) => {
      // console.log(response.data);
      return response.data
    })
    .catch((error) => {
      console.log(error)
    })
}
Enter fullscreen mode Exit fullscreen mode

This will now on a successful API call return the body of the response and if it's unsuccessful will print the error in the console.

Part 2 - Handling the API call within React

Now we need to do the API call when the page is first loaded, the first instinct is to run the fetchRandomUser function inside the useEffect hook provided by React. However, this is the last thing you want as this can cause race conditions which means sometimes it will work sometimes it will not, you do not know!

How do we do it then?! We use useCallback, useState, and useEffect all together:

Inside App.tsx

import React, { useCallback, useEffect, useState } from 'react';
import { fetchRandomUser } from './api/User';

function App() {
  const [userData, setUserData] = useState([])

  const loadUserData = useCallback(async () => {
    setUserData(await fetchRandomUser())
  }, [])

  useEffect(() => {
    loadUserData()
    console.log(userData);
  }, [loadUserData])

  return (
    {/*Application*/
  );
}
Enter fullscreen mode Exit fullscreen mode

To understand what is happening here we've created a state called userData using useState, and we're providing it an empty array as it's initial value.

We're then defining a function called loadUserData using useCallback with an asynchronous function, which sets the userData with the return value of our fetchRandomUser method created in api/User.ts inside, and an empty dependency array.

Finally we call the loadUserData function inside the userEffect, when the loadUserData function is initiated aka when the App component renders, and for debugging purposes I've added a console.log().

All of this generated the following output into the console:
API Console Log

Part 3 - Creating the Navbar component

Now the part where the user can see all the work we just put in. Like we did previously we'll create a new <Navbar.Section> in the components/navbar/CustomNavbat.tsx component. To specify we'll also be creating it outside of the <Group> component, as it is not to be grouped with the navigation buttons.

<Navbar.Section>
   <Button variant='subtle' fullWidth>
     User
   </Button>
</Navbar.Section>
Enter fullscreen mode Exit fullscreen mode

This creates this:
User Component

Now how do we get our API data from the App component into the CustomNavbar component?

Part 4 - Little bit of drilling

Prop drilling in React is a frowned upon practice and there are plenty of React state management libraries out there such as Redux and MobX. However, for the ease of creating this walkthrough we'll just do a little bit of drilling, I will be covering state management libraries soon I promise!

To pass the data to the CustomNavbar component we'll simply add it as a prop in the component in the App.tsx file.

<CustomNavbar userData={userData} />
Enter fullscreen mode Exit fullscreen mode

Now in CustomNavbar.tsx we need to import this prop as such:

function CustomNavbar({ userData }) {}
Enter fullscreen mode Exit fullscreen mode

Then you can refer to the contents of the userData within the component. For example we want to print the Title, First, and Last name of the person as a sort of greeting. We can do that as such:


const { name } = userData.results[0]
const { title, first, last } = name

return (

  {/*Rest of Navbar*/}

  <Navbar.Section>
    <Button variant='subtle' fullWidth>
      {`${title} ${first[0]}. ${last}`}
    </Button>
  </Navbar.Section>
)
Enter fullscreen mode Exit fullscreen mode

This produces the following:
Data drilled

Outro

For now this is all we will complete, later on we will be further customising the component and doing more development with the Mantine component library.

Thanks for ready, please leave a like and comment!

Top comments (5)

Collapse
 
adberger profile image
Adrian Berger

This doesn't seem to work for me.

This part doesn't always return the random user:
const [userData, setUserData] = useState([])

const loadUserData = useCallback(async () => {
setUserData(await fetchRandomUser())
}, [])

useEffect(() => {
loadUserData()
console.log(userData);
}, [loadUserData])

Most of the time the array is empty.
Any ideas? Is there a working examples in a gist or something?

Collapse
 
samp_reston profile image
Sam Preston

Are you importing the fetchRandomUser function from a separate api.js file or is the function contained within the component?

Collapse
 
adberger profile image
Adrian Berger

Just like in your example from a separate file:
import { fetchRandomUser } from './api/User';

Thread Thread
 
samp_reston profile image
Sam Preston

And you have the function being exported as so?

export async function fetchRandomUser() {
  return await axios.get('https://randomuser.me/api/')
    .then((response) => {
      // console.log(response.data);
      return response.data
    })
    .catch((error) => {
      console.log(error)
    })
}
Enter fullscreen mode Exit fullscreen mode
Thread Thread
 
adberger profile image
Adrian Berger

Yes