Setting up a React app with styled-components to consume a Node API
Tags: react, styledcomponents, api
Published: 2020-10-10 17:53:33

Hey there,

In the last [tutorial](https://dev.to/souzamarlon/setting-up-a-rest-api-with-node-js-and-express-js-3fl2), we learned how to set up a REST API with node.js and express. In this tutorial, we are going to set up a React App with styled-components to connect to the API from the last tutorial.

I hope you can learn something from this tutorial and I can learn something with your feedback.

**Before start, you need to have the back-end installed and also running. You could read this [tutorial](https://dev.to/souzamarlon/setting-up-a-rest-api-with-node-js-and-express-js-3fl2) or just clone this [project](https://github.com/souzamarlon/nodejs-express-setup) and follow the instructions.**

###Requirements:
- Yarn ([Documentation](https://classic.yarnpkg.com/en/docs/install/#arch-stable)).
- Visual Studio Code ([Download](https://code.visualstudio.com/#alt-downloads)).

## So let’s get started!
![Alt text of image](https://media.giphy.com/media/cjhzPSRRF0vk3WBS93/giphy.gif)

## What is React?
> React is a declarative, efficient, and flexible JavaScript library for building user interfaces. It lets you compose complex UIs from small and isolated pieces of code called “components”.
[Reference](https://reactjs.org/tutorial/tutorial.html)

## Starting the project:

The first step will be creating the project using the toolchain *Create React App*:

```bash 
$ yarn create react-app reactjs-styledcomponents-setup && cd reactjs-styledcomponents-setup
```

### Why do we need to use *Create React App*?
This toolchain provides a development environment to help us to have a better experience and not wasting time configuring many build tools in every new project.

You can have more information [here](https://reactjs.org/docs/create-a-new-react-app.html).


You might have these files in your folder:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/z3067b3c9xqlek573gnq.JPG)


We can delete some files that we won't use in this tutorial:

```bash 
$ cd src && rm -Rf App.test.js logo.svg serviceWorker.js setupTests.js App.css
```

Open the *index.js* file and then delete the following lines:
``` 
...
import * as serviceWorker from './serviceWorker';
...
serviceWorker.unregister();

```

Also, we need to delete the following lines in the *App.js* file:
``` 
...
import logo from './logo.svg';
...
<img src={logo} className="App-logo" alt="logo" />

```

We can start our project now, you should go to your console to digit the command line below:

```bash 
$ yarn start
```

We deleted the unnecessary files, we can move forward to the next step.

## ReactDOM

> The react-dom package provides DOM-specific methods that can be used at the top level of your app and as an escape hatch to get outside of the React model if you need to. Most of your components should not need to use this module.
[Reference](https://reactjs.org/docs/react-dom.html)

Ok, we learned what is a react-dom but you might be thinking what is DOM?

![Alt text of image](https://media.giphy.com/media/60rGgmwg5MegB9yZ2n/giphy.gif)


### What is DOM?
The Document Object Model (DOM) is a programming interface for HTML and XML documents that will allow the javascript to add/change/remove HTML elements, attributes, CSS styles, and events.

You can read more [here](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Introduction).

We learned about *react-dom* and DOM, we will look at how to use React Dom.

Open the *index.js* file, it can be found in the *src* folder. You will see some lines and one of these lines will be the *ReactDOM.render()*.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/sxm5yihm50hsntmof4lw.JPG)

Basically, the *react-dom* package provides some specifics DOM methods, and *render()* will be one of the methods that will be used in this tutorial.

#### render():
> Render a React element into the DOM in the supplied container and return a reference to the component (or returns null for stateless components).
[Reference](https://reactjs.org/docs/react-dom.html)

In this case, the component *App* is the React element that will be rendered into the DOM in the supplied container that contains the id root and accomplishes that we are using *document.getElementById('root')*.

#### What is getElementById()?

This method returns the element from the HTML document based on the id attribute.

[Reference](https://developer.mozilla.org/pt-BR/docs/Web/API/Document/getElementById)

You will be able to find the *div* tag with the id root opening the file *index.html*, this HTML file will be found in the public folder.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/uvf6fhuajpw6r4z3mepo.JPG)

Probably you saw the *React.StrictMode* when you opened the *index.js* and I believe you are thinking... "What is it that?". The *React.StrictMode* won't be useful in this tutorial but it is in the *index.js* for default, and I won't mind keeping it and also explain how works.

![Alt text of image](https://media.giphy.com/media/3o7WTIVuAOn8lBYN7W/giphy.gif)

#### What is React.StrictMode?
In our development journey is very common to find problems in the application, this tool will highlighting potential problems in development mode adding warnings at runtime. If you want to use this tool you just need to put it around the components.

The warnings will appear on your browser console.

The benefits of this tool:
- Identifying components with unsafe lifecycles;
- Warning about legacy string ref API usage;
- Warning about deprecated findDOMNode usage;
- Detecting unexpected side effects;
- Detecting legacy context API.

You can have more information [here](https://reactjs.org/docs/strict-mode.html).


We learned about *react-dom* and we can move forward to the next step of this tutorial.

## Creating a basic page to consume our API

We are going to create a page to look at how the Http requests work on the client-side.
This part of the tutorial will be great because we will see examples of how the web application consumes an API.

We need to install the *axios* library:

```bash 
$ yarn add axios
```

### Why do we need to install this library?

This library will provide us the HTTP request that we will use during this tutorial.

Open the *App.js* and add the following lines:

```
import axios from 'axios';

...
function App() {
   const api = axios.create({
    baseURL: 'http://localhost:3333',
   });

return(
...
)
}

```

In the code above, we are creating an instance named *api* to receive all the methods and avoid using the same URL for all requests that will be created.

From now on, we are going to write some examples using HTTP get, post, put, delete requests.

![Alt text of image](https://media.giphy.com/media/xUA7aPNq3XIXnLWtY4/giphy.gif)

### GET:

In this example, we will receive the users from our API, and then we are going to show these users in the browser.

Add the following lines in App.js:

```
import React, { useEffect, useState  } from 'react';

...
function App() {
  const [users, setUsers] = useState([]);
  ...

useEffect(()=>{
    async function getUsers(){
    
      const response = await api.get('users');
  
      const newArray = response.data.map((item) => ({
        id: response.data.indexOf(item),
        user: item
      }))

      
      setUsers(newArray);
     }
        
     getUsers();

   // eslint-disable-next-line react-hooks/exhaustive-deps
   },[])

return(
...
)
}

```

In the code above, we have a function responsible to get the users from the API and then to save these users using the *setUsers* from the state hook.

If this is your first time using React Hook, you might be thinking... "What is a Hook? and What does *useEffect* and *useState* do"?

#### What is a Hook?
> Hooks are functions that let you “hook into” React state and lifecycle features from function components. Hooks don’t work inside classes — they let you use React without classes.
[Reference](https://reactjs.org/docs/hooks-overview.html#but-what-is-a-hook).

This tutorial will only cover two basics Hooks but if you are interested in all the Hooks available so you can get more information [here](https://reactjs.org/docs/hooks-reference.html).

#### What does useEffect do?
> By using this Hook, you tell React that your component needs to do something after render. React will remember the function you passed (we’ll refer to it as our “effect”), and call it later after performing the DOM updates. In this effect, we set the document title, but we could also perform data fetching or call some other imperative API.
[Reference](https://reactjs.org/docs/hooks-effect.html)

Only thinking in performance, *useEffect* is amazing because React will prioritize the rendering of your application before fetching the data. Maybe we have many users to receive from API that it could affect negatively the application if we need to load everything at the same time but this won't happen using UseEffect.

#### What does calling useState do?
> This is a way to “preserve” some values between the function calls — useState is a new way to use the exact same capabilities that this.state provides in a class. Normally, variables “disappear” when the function exits but state variables are preserved by React.
[Reference](https://reactjs.org/docs/hooks-state.html)

The *useState* will help us to store the array received from the API because we are going to use this array in other parts of our code.

Right now we need to create the page to show the users on the browser.

The first step will be the styled-components installation.

```bash 
$ yarn add styled-components
```

This framework will allow us to write HTML elements with CSS as a component. Styled-components give us the freedom to use the same CSS code in more than one React component.

You can read more [here](https://styled-components.com/docs).

We need to create the styles.js file inside of the src folder:

```bash 
$ touch styles.js
```

Open the styles.js and add the following lines:

```
import styled from 'styled-components';


export const Container = styled.ul`
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    width: 100%;
    max-height: 100%;
    height: 500px;
    list-style: none;

    li{
        margin-top: 10px;
    }

`;

export const Input = styled.input`
    height: 28px;
    width: 200px;
    margin-right: 5px;
    padding-left: 4px;
    border: 0.5px solid #eee;
    border-radius: 4px;
`;

```

The structure is different from than classic CSS document because we are using *styled-component* to create a *ul* tag with some CSS properties and then we are exporting to the *Container* variable.

*Input* is the same but it has a different tag and CSS properties.


In our App.js we need to add the following lines:

```
...

import { Container, Input } from './styles'

function App() {
  ...

return(
   <Container>   
         {users.map((item)=>(
               <li key={item.id}>                         
                   <Input value={item.user} />                                 
                </li>
            ))}              

  </Container>
)
}
```

We are going to use the *input* element to show the values and also edit them. You will understand the reason for using the same element to show the value and edit it in the next step of the tutorial, where we will create the edit function.

*Open your browser to access your React App (http://localhost:3000/), you might have something like this:*

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/tietwo965da3f8yfz1mz.JPG)

It is a very modest page but it is possible to show all the users on the browser.

*Remind you: You need to have the back-end running. At the beginning of the page, I gave you some options on how to get the back-end from this tutorial.*

Very simple, right?
![Alt text of image](https://media.giphy.com/media/xUOxfaD566vU0qg09O/giphy.gif)


### PUT:

We will create one example using the PUT request to change the user name.

The first step is to add some lines in *styles.js*:

```
...
export const Button = styled.button`
    margin-left: 5px;
    border: 0;
    border-radius: 5%;
    background: ${props=> props.backgroundColor};
    color: #333;
    height: 30px;
    width: 70px;
    cursor: pointer;
`;

```

And now, we need to add the following lines in App.js:

```
...
import { Container, Input, Button } from './styles'

function App() {
const [edit, setEdit] = useState({isEdit: false, id: 0});

...

function updateUser(e, id){    
    const userUpdated = users.map((item)=> {
      return item.id === id ? {id: item.id, user: e.target.value} : item;
    });
   
    return setUsers(userUpdated);
   }

   const handleInputChange = async (id) =>{     
      await api.put(`users/${id}`, { user: users[id].user });
    
   }

return(
   <Container>   
         {users.map((item)=>(
               <li key={item.id}>                         
                  <Input value={item.user} onChange={(e)=> updateUser(e, item.id)} disabled={edit.isEdit && edit.id === item.id ? false : true}/>
                  <Button onClick={()=> handleInputChange(item.id)} style={{display: edit.isEdit && edit.id === item.id ?  null : 'none'}} backgroundColor={'#C0F9B6'}>Submit</Button>
                  <Button onClick={()=> setEdit({isEdit: !edit.isEdit, id: item.id })} backgroundColor={'#87B6FD'}>Edit</Button>                           
                </li>
            ))}              

  </Container>
)
}
```

*Replace the input from the first example to this new input.*

We are using the map method in the *updateUser* function to change the object *user* based on the id so we can show the new values in the *input field* every time the letters were typed.

In the arrow function *handleInputChange*, we will send the *user* object using the *api* instance to call the HTTP Put request. 
The *id* is a parameter necessary to update a user based on the array index.

*Open your browser to access your React App (http://localhost:3000/) and try to edit one user, you might have something like this:*

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/wucrwv34637fpqpnf23x.JPG)


### DELETE:

We learned how to edit but now we want to delete, so we will use the HTTP delete request to remove the users that we don't want to keep in our application.


Add the following lines in App.js:

```
...

function App() {
...

const handleDelete = async(id)=>{
     
    const response = await api.delete(`users/${id}`);

    const newArray = response.data.map((item) => ({
        id: users.indexOf(item),
        user: item
      }));

    setUsers(newArray)
}

return(
   <Container>   
         {users.map((item)=>(
               <li key={item.id}>                         
                 ...
                   <Button onClick={()=> handleDelete(item.id)} backgroundColor={'#FA6C6C'}>Delete</Button>                              
                </li>
            ))}              

  </Container>
)
}
```
The delete button will execute the arrow function *handleDelete* every time is pressing. This arrow function will delete the user using the *api* instance to call the HTTP delete request. 
The *id* is a parameter necessary to delete a user based on the array index.

*Open your browser to access your React App (http://localhost:3000/) and try to delete a user, you might have something like this:*

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/cxbjmzb29za54a09ccca.JPG)


### POST:

I left the best part for last. 
Finally, we will look at how to add more users using the HTTP Post request.

![Alt text of image](https://media.giphy.com/media/TlK63EzncfsZqllKr5u/giphy.gif)

We need to add more lines in our *styles* file:

```
...
export const AddUser = styled.div`
    display: flex;
    justify-content: space-around;
    margin: 20px auto;
    width: 20%;
`;
```

And then we need to add the following lines in App.js:

```
...
import { Container, Input, Button, AddUser } from './styles'

function App() {
...

async function handleAddUser(){

    const response = await api.post('/users', { user: addUsers})

    const newArray = response.data.map((item) => ({
      id: response.data.indexOf(item),
      user: item
    }));


  setUsers(newArray)

}

return(
   <Container>   
         {users.map((item)=>(       
                 ...

            ))}
   <AddUser>
         <Input onChange={(e)=> setAddUsers(e.target.value)} placeholder="Type the user name..."/>
         <Button onClick={()=> handleAddUser()} backgroundColor={'#C0F9B6'}>Add</Button>                      
   </AddUser>                

  </Container>
)
}
```

The *setAddUsers* will save the words typed in the input element and then the *handleAddUser* function will send the user object using the *api* instance to call the HTTP post request and also it will use the map method to create a new array.


*Open your browser to access your React App (http://localhost:3000/) and try to create a new user, you might have something like this:*

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/isk3elq8zrnp6kzyg0b0.JPG)


## Conclusion
We learned how to set up a React project with styled-components and make some HTTP requests on the client-side.
Clearly, all the changes we made to the array will disappear when the back-end is restarted because we are not saving in a database but it was a good example of how to consume an API.

I am proud of you and myself because we finished another tutorial. I hope I have contributed to your long trajectory of knowledge.

You can access the project [here](https://github.com/souzamarlon/reactjs-styledcomponents-setup)

See you in the next tutorial!

![Alt text of image](https://media.giphy.com/media/pGnQ7i6DuPKmc/giphy.gif)