What's the 101? the useState React Hook

What's the 101? the useState React Hook

Learn the useState hook like a Pro. A deep-dive into how it works under the hood, use cases and statefulness!

Table of contents

No heading

No headings in the article.

My mentor always told me,

“for every new concept you learn, there's three major whys”.

Why does it work this way? why do we have to use it this way? why was it created? And in this junior dev thriller, I’ll be attempting to answer these questions about the useState hook in React.

To understand the purpose of hooks, we need to shed some light on React’s core principle — Rendering efficiency. The major difference between React’s behavior and Vanilla JavaScript is it’s interaction with the browser DOM. React implements a virtual DOM which interfaces with the real DOM tree to ensure an efficient updating process. Check for props and state changes in every component, update the DOM with observed changes, leave unchanged components the same(memoize).

What is the useState Hook?

The react way of storing the application state and updating the view elements. React simplifies storing and managing information about our application via the useState hook. This ensures the state is persisted within the component and updated with each re-render — a behavior we term statefulness!

How do we use it?

useState Hook

We start with destructuring the hook and setting a name for our variable and its setter method. Then we provide a default value to our variable on the right-hand side of the assignment operator.

This immediately gives us access to reading and updating our state via the returned variable and setter method.


How does React opt to reason about it?

“Well, let’s see…I need a way to SAFELY store and update information about my app, make that information local to the component it’s created in, then make sure it triggers a component re-render at the right time”.

React only lets us modify the state variable via a setter method, which ensures state values cannot be randomly reassigned or mutated without the setter method provided at declaration.

let’s take a look…

protected state

How was it designed?

To truly understand things, I end up needing to rebuild them myself. Examining the implementation of hooks outside the browser should make better sense of what’s going on under the hood.

useState in Nodejs


Understanding stateful behavior

A core and often unexplained principle in software engineering is “state” and the derivative word “stateful”.

Statefulness refers to storing interactions and using the data in future interactions. Often, we need to implement operations that rely on data from a previous operation; so we store the data in “state” and update it with every new interaction.

In React, we enable this behavior at the component level via the useState hook.

Statefulness also ensures a “protected state”; meaning functions now have internal variables that can only be accessed within them and are “preserved” with every new call to that method. React hooks implements a protected state by providing a setter method as the only access point to the internal state.

In vanilla JavaScript, this behavior is enabled via “closures” (a more advanced topic I won’t be diving into here) — developer.mozilla.org/en-US/docs/Web/JavaSc..


useState vs normal variable declarations

“why implement a separate way to manage local state? why don’t we just use regular variables like in Vanilla JavaScript? What’s the trade-off?”

In all fairness, we can use regular variable declarations within React, but the general rule of thumb is, “if it directly affects the view layer, hook into statefulness”.

This is because changes to state trigger re-renders in the view components, but changes in regular variables only change locations in memory, meaning relying on regular variables to handle the view-state will result in our application being out of sync.

Another reason is, with each call to the component and resulting re-render, there is an “update” to state — meaning values are “preserved within function calls, while for regular variable declarations, there is a “reset” to the initial value.

here’s an example

State vs Local Variables


Use Cases

“When should I use the useState hook? when do we favor local variables instead? can it be used to implement global state?”

use Case #1 -> Parent-Child props

When passing state as props from parent to child components, we declare the state values in the parent component using the useState hook.

Parent-child props

use Case #2 -> Internal Component State

When we need to create state that is bound to specific components in the view, we use the useState hook.

Internal State

use Case #3 -> Custom Hooks

When we need to create local state variables for custom hooks, we can use the useState hook too!

Custom Hooks

use Case #4 -> Context Providers

When we need to create state values and pass them into a Global context object, we use a store component with internal useState variables and pass that as the value to the context provider.

Context Provider

use Case #5 -> Lazy Loading

"Load it when I need it!"

A performance optimization concept which lets us initialize expensive pieces of state only when the user is ready to consume it. Lazy-loading can be observed when reading through most news feeds; you notice images and long blocks of text only load-in as you scroll through.

Here's an example of implementing lazy-loading for a counter variable.

Lazy-Loading

use Case #6 -> Grabbing Previous State

A super interesting part of the useState hook is how it gives us access to previous values of state when needing to perform operations on the current state. We implement this by using a callback within the setter method.

My example will be the famous toggle pattern.

Previous State

We initialize state to false, then the useState setter method let's us reference that initial value of state within a callback, which we use to determine the next state value. Pretty neat!


Non-use Case -> Accepting Parent props

A general rule of thumb is, when data is derived from props (parent components passing data to children), we use local variables to store said data. The reason is, changes to props from the parent component will trigger re-renders in the child component and state changes also trigger re-renders. We need to avoid unnecessary re-renders and only store data in state when it isn’t reliant on parent components.

I hope this article helped you gain some insights on the workings of the useState hook in React…here’s to curtains on this little deep-dive.

As always, I’m super open to correction and critique so let’s get educative conversations going!``

Feel free to contact me for more delightful conversations about React!

twitter.com/elixir_js via email -> github -> Github.com/Geller99