Exploring React Hooks - useState / useEffect
Published: 2023-01-09 14:02:07

In this blog, I would like to write a bit about the functionality of my forum app, a topic thats given me alot of trouble, and share some knowledge I've received in learning ReactJS. In my initial attempts, I was able to attain a basic idea of Reacts syntax and how components were organized. However, I was having a ton of trouble utilizing one of Reacts most important features, hooks.

A hook is a JavaScript function built into react that is used to isolate reusable parts from a functional component and can manage the applications state and side effects. The first hook you should learn in the useState hook, which is essentially used to hold state values or data, and is paired with a function that is used to update that state's value. It is very useful to utilize the useState hook to hold very specific pieces of data, and to be able to modify it with event listeners and causing that value to re-render on the page.

As for a brief overview of my project, the app I built is basically a forum app which allows users to create an account by inputting their username and (optional) URL of an image they would like to use for their avatar. There are 4 client side routes: Home, Chat, Users, Login. Whatever page the user attempts to visit, they are redirected to the Login page, where they must either create a new account or log into an existing one. The user may then go to the ‘Users’ page to view all existing users in the application, or the ‘Forum’ page to view and create posts. The user may also update their profile image by adding in a new URL within the login page. CRUD operations are being used to communicate with my backend API, POST request to messages and user data, GET requests on first render and when the user logs in, PATCH; to update users profile, and DELETE to erase any comment that is submitted. Each requests calls a setState function to keep whats rendered consistent with what's in the database.

The project may be viewed here:
https://fusion407-chat-app.netlify.app/

Here is the repository:
https://github.com/fusion407/chat-app-frontend

Now back to states.

I declared most of my states here in the top level off my app (App.js)
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nx90p8h1qvq7cwfnqq9b.png)

[isLoggedIn, setIsLoggedIn]  -   is a boolean I am using in order to keep track of whether or not the user is logged in or not. 

[allUsersData, setUsersData]  -  is the state that holds all the users data such as username, and avatar image that is being fetched from my backend API.

[loggedInUser, setLoggedInUser]  -  is what holds information on the user that is currently logged in and using the app.

[messages, setMessages]  -  holds the message data being fetched from my backend API.

It is important to be mindful of which components you are declaring these states in and what kind of data they are holding. The reason I am holding these states specifically in my top level component is so I may pass this data along as props into its children components, so they may access its states values and be able to modify them with its setState functions.

Another example of using the useState hook would be in my Chat component and my Login component:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ulxujsjlnkjmjhevrxeg.png)

The purpose of this state is to keep track of the values within the form of each page. The value is assigned to the input with an event listener to change formData’s state, and an event listener is added to the form itself to make the data submission. On submit of these forms will make a POST request to my backend, saving the values within the input, then setting new states accordingly.

Here is what the return looks like for my Chat component.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/349nbzjgh8rxm0t4t0s6.png)
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pxdpyxvpe1c4n906yjxw.png)

There is an input form labeled, “New Comment:”, an event listener called onChange is tied to a function called handleChange. So when the user begins to write anything in this input box, setFormData is called to replace formData’s previous state and replace it with a new one. 

Here is what my handleChange function looks like:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0oyfaw2med31jo6voqqr.png)

Now when the user decides to click the “Add Comment” button, there is first a check to see if there is anything written within the formData, if not then nothing will happen. If the user successfully submits the form, the POST request is made, then setMessages will be called to take the messages array previous state, then add the value from the form to it.

My handleSubmit function:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/co9rk2jlez64yyjw7en5.png)

Again, it is important to know when to useState hook and which components to put them in. You want to think about “Which components do I want to be able to access this data?” and “What is the purpose and functionality of this state?”

Putting the useState aside, I would also like to briefly write about the useEffect hook - which is by far the hook I have had the most trouble learning so far. What the useEffect hook does is create side effects in your components and rebuilds each render cycle. In my project I have made use of useEffect to fetch the data for my allUsersData state, and messages state.

Here is my useEffect hook called in my top level component (App.js).

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y97oax36qs7kg7pr1a79.png)

Upon initialization of the app, these 2 functions are going to be called as the first argument, handleFetchUserData(), and handleFetchMessages(). These functions do as they say they do, fetch user data, and fetch message data from my API. The second argument takes in a dependency which will cause the useEffect to run each time the dependency has been modified. Having an empty dependency will cause the useEffect to only initialize the very first render, since I am fetching data and saving it into local states I only need to make the GET request call upon once upon intitalization.

Here is the functions being called in my useEffect:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fh8sqfb8q7lco03saow4.png)

GET requests are made to my backend, fetching the message data and user data then setting their states so the data may be used and passed in as props to its children components.

Just like with the useState hook, before you begin writing a useEffect, you must understand what you are writing it for. Are you using it to fetch data? Or to simply create a counter? What piece of data would you like to be re-rendered through its life-cycle? There are a lot of rules to react hooks and it is highly necessary to brush up on those rules so you may be able to write your hooks properly.