React and its Lifecycle Methods Explained
Tags: react, webdev, javascript, lifecycle
Published: 2020-12-20 09:07:41

#Overview

I started to write this just about Lifecycle Methods but realized that an intro about React might be helpful. 

When I began learning React, I jumped into the syntax without fully understanding the methodologies behind them. So perhaps this will benefit someone else in the same boat. 

While this is by no means an all-inclusive or exhaustive introduction, below are some things I found helpful in understanding this powerful library and it's lifecycle methods.

Of course, feel free to [jump straight to the lifecycle](#lifecycle). 

So... what is React? 


---


##Intro to React

React, is an amazing front-end JS library that allows you to build super performant single-page applications, with tremendous efficiency. 

###What is a single-page application? 
These are web applications that only serve one HTML file. Even if the user can navigate to 5 different pages, filled with loads of content — only one HTML file is provided by the server. (React is not limited to this setup, but it is most known for it.)

###How is that possible?
This is accomplished by updating the DOM (what you see in the browser) in a continuous and intelligent way, while leveraging JavaScript to write most of the site's code. 1 HTML file and a load of very thoughtful JavaScript makes the website...just...React. 

*(Glad to be the first one to make that joke. 😜)* 

###Ok, but how is THAT possible?
Among other things, React has a few very important tricks up its sleeve.

1. [JSX](#jsx)
2. [Components](#components)
3. [Props](#props)
4. [State](#state)
5. [The Virtual DOM](#vd)


#### <a name="jsx"></a> JSX

JSX is Javascript hybrid language that lets you write HTML, CSS, and JavaScript seamlessly on the same line, with only minor syntax changes. (🤯)  

React then renders and compiles the JSX into standard HTML/CSS/JS for the browser to read. 

For me personally, JavaScript didn't really click until I started writing JSX and saw the structure and functionality come together...

```jsx
<section>

  <h2>{paginationState ? "New Dev Work" : "More Dev Work"}</h2>

    <div className="justify-content-around">

        {projects.map(project => (
            <DevProjectCard
                key={project.id}
                img={project.img}
                title={project.title}
            />
        ))}

    </div>

</section>
```

#### <a name="components"></a> Components
Components are a way to break up JSX and pure JS (like API calls) into separate files. *[Modularization](https://dev.to/hiowenluke/why-we-should-split-long-code-into-small-functions-or-files-5gjl)* and *[Separation of Concerns](https://www.youtube.com/watch?v=VtF6aebWe58)* are concepts that fit nicely here.

While the concept of components is not unique to React, it is pretty synonymous with it. The idea is to have many small/lean component files, that each holds a little bit of feature-specific code. These are then combined together, creating more complex layouts. 

The benefit? Components can be reused in multiple places and their styles/functionality can travel with them. This can mean less coding and maintenance in the long run. 

In the example above, the `<DevProjectCard />` block of code was a component. It represents another file that holds code (JSX) on how the Dev Project Card should look and function. 

#### <a name="props"></a> Props
Now that the application is divided up into bite-sized components, we need a way to pass information between them. This is where Props come in. 

Props take information from a parent component and pass it down to a child component. 

This means children components can focus on just providing structure for information but do not need to worry about **what** the actual info is. 

*(It is important to note that props can only travel down. A child component can't pass information back up to its parent.)*

In our example, `<DevProjectCard />` provides a way for an image and title to look in some sort of UI card element. But we are using props `img={}` and `title={}` to pass down what the actual image and title should be. By not hardcoding the information into `<DevProjectCard />`, this component can be used in more places and ways.

```jsx
<DevProjectCard
  key={project.id}
  img={project.img}
  title={project.title}
/>
```

*Note: The above example is using a `.map()` array method to create multiple `<DevProjectCard />` components, each with unique images and titles. The `key={}` is actually not a prop, but a method that is required on dynamically generated mapped lists in React.* 


#### <a name="state"></a> State
Another essential way to handle information and functionality in React is by using something called State.

State lets you temporarily store unique information within a component. As soon as the page is refreshed, the state is removed. But until that point, it is a powerful way to quickly control functionality and content. 

For example, perhaps we have a button that loads more Dev Project Cards to the page. Using state, we can store a value of `true` when that button is clicked. 

Then we can reference that state in an HTML headline to dynamically show different text if that state is true or false. 

```jsx
  <h2>{paginationState ? "New Dev Work" : "More Dev Work"}
```



#### <a name="vd"></a> Virtual DOM
The Virtual DOM is a copy of the real DOM the browser uses. This is where everything we have talked about so far comes together!

The real DOM is pretty slow to update and when you change something in the layout, the whole page needs to re-paint. 

Instead, React uses this Virtual DOM to compare against the real DOM, seeing if any components have changed. It uses changes in states and props as signals that something is now different.

If a state and/or prop has changed, React uses the Virtual DOM to only update the component(s) that were affected. This means the real DOM does not need to refresh the entire page if one or two things changed. Again 🤯!
 
###But how does it know to do this? 
Ok deep breath...So we write powerful JSX in well-organized components, that control their functionality with state and speak to other components with props — all of which is updated for the user via the Virtual DOM...whew. How does the Virtual DOM know when to check for changes in states and props???

React checks for these changes at strategic points and these are called Lifecycle Methods. 🎉

---

## <a name="lifecycle"></a> Lifecycle Methods

Lifecycle methods are how React compares the current code against the virtual and real DOMs. It dictates what code should be assessed and at what point. 

Before going further it's important to note, that React originally started with using **Class-based** components. These handle state and pass down props to **Presentation** (or dumb) components that only display the content. Lifecycle Methods are specifically used in Class-based components.  

With the release of `version 16.8` React introduced a new toolset called **Hooks**. Hooks allow you to turn presentational components into functional components that have all the power of their class-based counterparts, but with (usually) less code needed. 

The `useEffect` hook replaces all lifecycle methods and I will cover it at the end as well. However, many applications still use class-based components, so it is important to understand their lifecycle methods. 

###It is lifecycle method time! 
Below are the three I use the most, but there are more that are less commonly used. In the end, I will include a link to their documentation for further exploration. 

####componentDidMount() 
This will execute any code inside of it, directly after a component is mounted in the DOM. One of many use cases for this is making an API call for new data.   

```jsx
componentDidMount() {

  axios.get('https://api.website/users')
    .then(res => {
      this.setState({ users: res.data });
    })
    .catch(error => {
      console.log(error);
    });

}
```

####componentDidUpdate() 
This will execute code directly after a component has been updated through state or props. 

A common example is recalling an API that was set up in `componentDidMount()` to see if there is new data. However, this can lead to infinite loops or at least unintentional network calls. 

To prevent this, `componentDidUpdate()`provides the optional `prevState` and `prevProps` arguments to check if the last versions are different. If they are the same, the code won't be run again and nothing will be re-rendered. 

```jsx
componentDidUpdate(prevProps) {

  if(this.props.users !== prevProps.users) {

    axios.get('https://api.website/users')
      .then(res => {
        this.setState({ users: res.data });
      })
      .catch(error => {
        console.log(error);
      });

  }

}
```

Often times the same code will be run in both methods. `componentDidMount()` will set it up and `componentDidUpdate` will check for changes. (This is something hooks streamlines.) Because of this, it can be helpful to place the duplicate code into a helper function and call it in both methods. 

```jsx
// Funtion is called when component mounts
componentDidMount() {
  this.fetchUsers()
}

// React will call the function if there is a change
componentDidUpdate(prevProps) {
  if(this.props.users !== prevProps.users) {
    this.fetchUsers()
  }
}

// Helper Function
fetchUsers = () => {
  axios.get('https://api.website/users')
    .then(res => {
      this.setState({ users: res.data });
    })
    .catch(error => {
      console.log(error);
    });
}
```




####componentWillUnmount()
This will call right before a component is unmounted and destroyed. 

It can be used to stop timers and canceling network requests that were first called in `componentDidMount()`. This helps prevent memory leakage. 

You never call `this.setState()` in this method, because that instance of the component will never be rendered again. This can throw off React from reading the state correctly. 

In the example below we are telling Axios to eject some interceptors that were set up to handle global errors. 

```jsx
componentWillUnmount() {
  axios.interceptors.request.eject(this.reqInterceptor);
  axios.interceptors.response.eject(this.resInterceptor);
}
```

---

###Hooks! (RIP Lifecycle Methods?)

As mentioned, with the release of `version 16.8` React introduced **Hooks**. Class-based components were no longer needed to handle state and updating the Virtual DOM. A new age of coding in React was introduced with functional components and their "import-as-needed" hook counterparts. 

In one block of code, the `useEffect` hook replaced the functionality of `componentWillMount()`, `componentWillUpdate()` and `componentWillUnmount()`.

####useEffect

In its simplest form, `useEffect` takes in a call back function and runs on every render, mimicking the `componentDidMount()` and `componentDidUpdate()` methods. 

Every time the `useEffect` runs, it creates a new function behind the scenes, tying it to that particular render. 

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

useEffect(() => {
  console.log("This runs everytime the component renders.");
});
```

`useEffect` also takes an array as a second parameter. If left empty this will run its code one time when the component mounts.  (`componentDidMount()`) 

```jsx
useEffect(() => {
  console.log("This runs when the component mounts.");
}, []); 
```

The array can also hold one or more props and state values. React compares the last render to this value(s) and if they haven't changed, will skip the effect.  But if the value(s) have changed to what was last rendered, the effect will run again. (Just like `prevState` and `prevProps`.)

```jsx
useEffect(() => {
  setUsers(props.user);
}, [props.user]); // reruns when props updates 
```


The callback function can also return its own function. This is used to clean up any side effects previously run, to prevent memory leaks. Such as subscribing to a network request. (Just like `componentWillUnmount()`)

```jsx
useEffect(() => {

  setUsers(props.user);

  return = () => {
    axios.interceptors.request.eject(this.reqInterceptor);
  }

}, [props.user]); 
```


`useEffect` also lets you separate concerns, by having multiple `useEffect` hooks on the same component. For example, one handles users being changed on props and the other handles animations being triggered.

```jsx
useEffect(() => {
  setUsers(props.user);
}, [props.user]); 

useEffect(() => {
  triggerTitleAnimation();
}, []); 
```

---


##You did it! 😄

Nice job sticking through the end. Together we went through what makes React so performant. 

####Summary

* JSX combines HTML, CSS, and JavaScript to make writing code more seamless than ever. 

* Components segment code into separate files and use props to speak to each other. 

* State stores content and can be used to trigger functionality. 

* Together Props and State are used to update the Virtual DOM, which creates a super-fast browsing experience. 

* All of this is managed through Lifecycle methods and their modern hook counterpart, the `useEffect` hook.

I hope this has helped clarify how some of React works and enables you to create something cool. Happy coding! 🤓

**Let me know below:** *Do you reach for lifecycle methods or the `useEffect` hook when working in React?*  

---

##Further Reading
[React Documentation on Lifecycle Methods](https://reactjs.org/docs/react-component.html)
[React Documentation on Hooks](https://reactjs.org/docs/hooks-effect.html)
[React The Complete Guide](https://www.udemy.com/course/react-the-complete-guide-incl-redux/)

---

*Header image designed with [Adobe Photoshop](https://www.adobe.com/products/photoshop.html)*