React Hooks: How to use useEffect()

Hossein Ahmadi
JavaScript in Plain English
6 min readAug 26, 2019

--

Review

In the last article I’ve introduced React Hook and basic principals of useState() and finally we made our first custom hook. As I mentioned in React Hooks for beginners, Sweet and a little complex after understanding core concepts of useState() we’re going to inquire more in hooks and the next subject is useEffect(). One of the most important and useful parts of hooks that every developer needs to work with it if chooses hooks. It’s a little challenging and a little bit hard to understand BUT if you think in hooks way, I assure you enjoy writing your codes using it.

Stay with me and I hope you understand useEffect() method and its usage at the end of this article.

About useEffect()

If you refer to ReactJS official documents and search for useEffect in the hook section first tip you’ll see is this:

If you’re familiar with React class lifecycle methods, you can think of useEffect Hook as componentDidMount, componentDidUpdate, and componentWillUnmount combined.

Lifecycle methods in class-based components are very important. Sometimes you want to fetch some data from an API when rendering a component, sometimes you want to do specific action when your component updates. Most important methods are componentDidMount and componentDidUpdate.

Do you remember a very important thing that was mentioned in last article?

Hooks are something that let you write Functional Components and still hook into class-based features and use them.

UseState let us to bring states to functional components. States and lifecycle methods are 2 big parts of class-based component’s features. UseEffect allow us to handle our logic in lifecycle methods. From the name of it you understand that useEffect will be called every time something affects your component.

Awesome! So obvious that it’s definition of componentDidMount and componentDidUpdate.

Photo by Joshua Aragon on Unsplash

Different uses of useEffect()

Okay! Let’s write some code to go deeply through useEffect(). In this part I would like to use ReactJS docs example with some important changes to practice and see usage of useState() and useEffect() clearly. Assume we want to declare a property in state what is an object. And has 2 properties: name and familyName. Initial state would be “name” and “family” and after rendering the component it should be changed to something else.

NOTE: You can trace your states by React dev tools extension in Firefox or Chrome.

First step: Define states

Second Step: Define useEffect()

As you see in the code the argument of useEffect() is a function that handles your actions when something affects your component. Let’s check the result:

Great! Like me you should see the name and familyName you choose in state.

But let’s check something else. I want to log a special sentence in useEffect to see how many times it will be called.

And the result:

Oops! Same as me you understand that useEffect has been called every time that component changed. This isn’t what we’re looking for. Our useEffect method is acting like componentDidUpdate now. If you’re familiar with componentDidUpdate we can control when it should act by conditions. Here in useEffect you can pass an array as the second argument. This array clearly tells react that just call useEffect when fields in me has been changed. So if you put ”name” in the array and pass it as second argument of useEffect(); your method will be called just when “name” changes.

Still this isn’t our answer. We want componentDidMount! To tell useEffect to act like componentDidMount just pass an empty array and everything will be perfect. Let’s check it:

And our logs:

Great! Now we have used different types of useEffect() and I hope you’ve realized the core concepts of useEffect().

Fetch data with useEffect

We want to go further and use our knowledge about React Hooks. We want to do an actual and useful task that all of us will be faced in real projects: Fetching Data from an API. Before we move forward you should know some tips:

1. We use axios to fetch our API. It’s too cleaner and easy to use. You can read about it here: Axios GitHub

2. We use rest countries global API. URL is: ‘https://restcountries.eu/rest/v2/all’

Okay! All setups are nice and enough. Our task here is to get list of countries from our API and show them in a bullet list.

We need to provide 3 variables in our state:

  1. Countries: list of our country to show them
  2. Load: to show a loading text until our fetch process completes. (to avoid async/await TypeErrors)
  3. Error: to show error returns from our fetch method instead of the country list

Alright! Declare our state:

Good! Now we fetch our API using axios in useEffect(). Don’t forget to pass an empty array as second argument because we want our useEffect act like componentDidMount.

Our load initial state is a Boolean type false and our error is undefined. When our component mounted, we fetch our API. If API returns status code 200 or OK, we set our countries array by returned data. But if our fetch process fails, we set an error equal to retuned error. In both cases we set our load “true” to show visitors the final result. And finally, our last step:

Great! We’re Done! We successfully fetched API in a functional component thanks to useEffect and handled loading and error.

Make our code cleaner

We can make our code cleaner. Let’s move our fetch method to another file and implement a get method for our entire project. Before we go further it’s important to know we’re going to use promises because fetching API takes time and we want to avoid TypeErrors. You can read about promises in Master the JavaScript Interview: What is a Promise? By Eric Elliott.

As mentioned by Eric Elliott:

A promise is an object that may produce a single value some time in the future: either a resolved value, or a reason that it’s not resolved (e.g., a network error occurred). A promise may be in one of 3 possible states: fulfilled, rejected, or pending. Promise users can attach callbacks to handle the fulfilled value or the reason for rejection.

So, we create a promise an tell him to do our action. Promise resolve us some answer or data if the action completes successfully or reject us with some reason if action fails. Now let’s create our getItems method in another file, for example generalMethods.js:

Now we can import and use it every time we want to fetch a get API. We just need to pass our URL. Be aware that now we can remove our load state and ignore it but don’t do it. Maybe our fetch process takes some time because of user’s internet speed or our server.

Nice and Clear!

Final talk

In my 2 articles about hook I tried to show you power and benefits of functional components and hooks. I understand if you are a little confused and have fear about using hooks. It’s normal. Class-based components are ruling in react for about 5 years and breaking the habits is too hard and frightening. But you should hit the target. Move slowly. Challenge yourself. Implement your classes by hooks in another project. Try to beat your habits and test hooks. I assure you’ll enjoy it. In next articles I’ll explain useReducer for developers who are using redux. And we will create a real web application using only functional components and hooks. You’ll see the modularity and beauty of hooks in next articles clearly.

If you liked this article and it was useful for you don’t forget to clap and feel free to contact me by email: hossein.ahmadi98@outlook.com

--

--