DEV Community

Cover image for Phase 2: UseState Hook
Tate Braeckel
Tate Braeckel

Posted on

Phase 2: UseState Hook

UseState is a useful hook used to track the state of a function component. In general, it

"refers to data or properties that need to be tracking in an application (w3schools.com/react/react_usestate.asp)."

Some common use cases are to keep track of information entered by a user in a form, toggle switches, buttons that fire other code that changes the state (conditional rendering), using a fetch (GET) request to obtain data from an API and store the response in state.

The useState Hook is particularly helpful, in that it (along with other hooks) allows for much more readable code, whereas the use of class components can be very clunky and filled with boilerplate code that isn't necessary in Hooks. UseState returns an array because an array is more flexible than an object.

Below I used the useState and useEffect Hooks for "ImagePage.js" for my Phase 2 project.

In this snippet I have de-structured a variable "art" that will hold the state value. The "setArt" is the function that will change the value of the state "art". The useState([]) is setting the initial value of the state "art" as an empty array. The initial value of state can be,

"an object, an array, a boolean, or any other type you can imagine."

Then within the useEffect hook, which is wrapping the fetch request to my db.json, the data is used to set state for the art variable. This is passed down to the "ImageList.js" component as props and the .map method is used to iterate over all the objects in the array. Values from each object mapped are then passed down to the "ImageCard.js" component to delineate the final JSX code that will be used for the DOM render for each object.

Holding this information in state is essential for smooth re-renders of pages when state changes, when a page is refreshed, etc. When a

import React, { useState, useEffect } from "react";
import ImageList from './ImageList';
import Search from "./Search";
import NewArt from './NewArt';

function ImagePage() {
    const [art, setArt] = useState([])
    const [searchArt, setSearchArt] = useState('')

    useEffect(() => {
        fetch(`http://localhost:8000/artwork`)
            .then((r) => r.json())
            .then(artArray => setArt(artArray))
    }, [])

    function addNewArt(myArt) {
        setArt([...art, myArt])
    }
Enter fullscreen mode Exit fullscreen mode

Another use case in my own project for useState is in the code below, which is in the "NewArt" component, which is essentially a form that a user can enter data into an create a new art image card on the art gallery page:

function NewArt({ addNewArt }) {
    const [title, setTitle] = useState("")
    const [year, setYear] = useState("");
    const [price, setPrice] = useState(0.00)
    const [newImage, setNewImage] = useState("")


    function handleSubmit(e) {
        e.preventDefault();

        let newArt = {
            title: title,
            year: year,
            price: price,
            imageUrl: newImage
        }

        fetch(`http://localhost:8000/artwork`, {
            method: "POST",
            headers: {
                "Content-Type": 'application/json',
            },
            body: JSON.stringify(newArt)
        })
            .then((r) => r.json())
            .then((myArt) => addNewArt(myArt))
    }
Enter fullscreen mode Exit fullscreen mode

Firstly, the function "addNewArt" is passed into this component as props, then called later in the component function. Next, the initial state is set for the new art which will be inputed by the user in the form fields (title, year, price, and imageURL), which are corresponding key/value pairs from the db.json which acts as my app's API.

Another function "handleSubmit", which is used to prevent page reload on submit and to set the state values to the corresponding value in the db.json, all within a variable named "newArt". Then a fetch(POST) is called which will use the prop of the function "addNewArt" from "ImagePage.js" to add the newly entered information into the state of 'art' or the array of art objects from the db.json. Thus, the useState hook helps to swiftly update state between multiple components in a concise manner.

Below is more of the "NewArt.js" component code, specifically the form for entering new art data into the gallery space. It highlights the inline use of setting state with the onChange event handler here:

<form className="form" onSubmit={handleSubmit}>
                <input className="formTitle" type="text" name="title" placeholder="New Art Title" value={title} onChange={(e) => setTitle(e.target.value)} />

                <input className="formYear" type="text" name="year" placeholder="Year Created" value={year} onChange={(e) => setYear(e.target.value)} />

                <input className="formPrice" type="number" name="price" step="0.1" placeholder="Price in $..." value={price} onChange={(e) => setPrice(e.target.value)} />

                <input className="formImage" type="text" name="image" placeholder="Image URL" value={newImage} onChange={(e) => setNewImage(e.target.value)} />


                <button className="formButton" type="submit">Add Art</button>
Enter fullscreen mode Exit fullscreen mode

Each input in the form, which is controlled because of passing the correlated state variable into the value, then uses the onChange event handler. In the onChange the event is called as an argument and calls the setter function that corresponds to the given initialized state value- which then resets the state value to the "e.target.value" or what data is entered in the input field.

This is repeated a few times in the form, as the same action and similar state updates are happening. Once these input values and their corresponding state is changed, and the submit button fires the "handleSubmit" function, the state variable is updated and the POST request happens, firing the DOM re-rendering and the db.json file to be updated.

The useState hook is an essential addition to React as it helps to update state in different variables, strings, objects, array, etc. without all the unnecessary boilerplate code that came with using class components for this. Additionally it simply cleans up the code as a whole. I have found React Hooks to be much more user friendly and cleaner to work with and look at than what I have seen of React class components. I am hopeful that even better updates to Hooks will come about and React will be even easier to use.

Top comments (0)