A Beginner's Guide to Managing React State with Hooks

A Beginner's Guide to Managing React State with Hooks

A Beginner's Guide to Managing React State with Hooks

Managing state can be one of the more complex aspects of working with React as a beginner. What data should be managed by state versus props, which components need to access state and where state should live are all questions I ask myself when planning a new React project. Redux is an alternative for managing state it may be a lot to add for a small project.

While building an app that queries the Spotify API for an artist, based on the user input, it made sense to store that input in state. That input value could be passed to the API, referenced in the UI ("Showing results for: adele") or elsewhere in the app.

I learned to set up state as an object (state = { key: value}) but did not know this only works in class components! And mine were set up as functional.

Yikes.

I did not want to make the conversion right away, so I did a quick Google search for an alternative. I landed on the useState React Hook and had to give it a try.

Implementation

Hooks are a somewhat mysterious aspect of React. I had not used one until now. Similar to other features in React like componentDidMount, Hooks are built-in, modular functions of React. That's it!

To get started using the useState Hook, it needs to be imported into your React file.

import React, { useState } from 'react';

Define State

Once useState had been imported into your file, you can create and set state values. For my app, I want to store the input from a text field in state.

Here's what setting that up looks like:

import React, { useState } from "react";

function App() {
  const [input, setInput] = useState("");
}

What useState does is it sets up a state variable and a function that will update that variable. In my case, the variable is named input and the function that updates input is called setInput. The empty string (") within useState is the default value for input.

From my understanding of the Using the State Hook docs, the state variable and it's update function can be named anything. But, it makes sense to name them what they are/what they do, especially if there are multiple state variables.

Now, we're ready to access and manipulate state within our app!

Reference State

Since state has been set up outside of a class, we do not need this.state to reference within our app. In the return() statement for App(), input is referenced as {input}.

Given the following example:

import React, { useState } from "react";

function App() {

  const [input, setInput] = useState("")

  // TODO: Write handleOnChange function

  return (
    <main className="App">
        <h1>Search for an artist</h1>

        <form>
            <input type="text" name="input" id="input" onChange={(e) => handleOnChange(e)} />
        </form>

        <h2>Showing results for: "{input}"</h2>

    </main>
  );

}

If the current value of the input was "adele", the h2 tag would render Showing results for: "adele" to the page.

Update State

To update the input variable in state, we'll use the setState variable we set up earlier.

In the code sample above, you see that the text input field has an onChange event. Each time the value of the text field changes (the user types in the field) a handleOnChange function is fired. This function will house the update function.

setInput could be used inline, but in my case it made more since to separate it into a handleOnChange function, since that function would perform additional operations.

To update state, we call setInput() and pass in the new value that will replace the current state.

Here's what handleOnChange looks like in my example:

 function handleOnChange(e) {

    setInput(e.target.value)
    // TODO: Perform other operations
}

That's it. The value of input has been updated.

Recap

To recap everything we've done:

  1. We imported useState into our functional component.
  2. Declared state variables and a function to update that variable with useState.
  3. Referenced the value of our state variable input in our and rendered onto the page.
  4. Updated input using our setInput function with the new value as the argument

And here's what our App.js file looks like now:

import React, { useState } from "react";

function App() {

  const [input, setInput] = useState("")

   function handleOnChange(e) {

    setInput(e.target.value)

    // TODO: Query the Spotify API with the value of "input"
    }

  return (
    <main className="App">
        <h1>Search for an artist</h1>

        <form>
            <input type="text" name="input" id="input" onChange={(e) => handleOnChange(e)} />
        </form>

        <h2>Showing results for: "{input}"</h2>

        // TODO: Render results of API call to the page

    </main>
  );

}

This is the very beginning of what React Hooks can do. There are some limitations, rules and take some getting used to. I highly recommend reading through their docs on Using the State Hook to see how useState compares to setting state in a class component.

Resources