Sitemap
codeburst

Bursts of code to power through your day. Web Development articles, tutorials, and news.

A Quick Intro to React Hooks with useEffect, useState, and useContext

6 min readJan 23, 2019

--

Press enter or click to view image in full size
Hooks on cups on hooks. Original photo by Chris Scott on Unsplash, poor editing by me

At React Conference 2018, the React team first introduced the concept of hooks and my mind was blown. Both from excitement, and confusion. Since then, hooks have become available in React 16.8, and the community is abuzz. At first, it was tricky for me to understand how to use the different hooks but since then I’ve started using them in a side project and am in love!

If you haven’t had the chance to look into them, nows a great time. They’re an excellent way to make code cleaner, make components smaller, and reuse logic.

What are hooks?

Hooks let us abstract different pieces of complexity from our functional components. They are regular functions that you import directly from the react library and call in your components. Different hooks do different things:

useEffect

useEffect is a hook for encapsulating code that has ‘side effects,’ and is like a combination of componentDidMount, componentDidUpdate, and componentWillUnmount. Previously, functional components didn’t have access to the component life cycle, but with useEffect you can tap into it.

useState

useState is a hook that encapsulates local state management. Previously, functional components were called “stateless components,” but no longer! With useState, we can utilize what seems like local state for storing values. Actually, they’re more like “state variables” that React keeps track of by the order you declared them. useState saves us from having to create class-based components for state-related responsibilities, since it gives functional components the power and flexibility to handle it themselves.

useContext

useContext is a hook for getting broadly shared application data from context providers. When they added the official context API to React in 16.3, I was really excited about the capabilities but hated working with the API. The need for functional rendering made sense, but I strongly disliked using it. Now with the useContext hook, we can utilize all that power without having to ugly up our code or the React Developer Tools component tree!

There are also other hooks that exist as of the 16.8-alpha, but they aren’t covered in this intro. You can find documentation on them here:

Learning by example

Personally, I learn better by trying things out and seeing examples than I do by reading overviews and concepts. The examples in the React documentation are great but purposefully simple, so it was easier for me to grasp the different hooks through more realistic examples. So for this introduction, I’m going to run through some code samples and explain how the featured hook works.

Note: Hooks only work in functional components!

Using native event listeners

This is a small functional component that renders an 𝗫 ‘close’ button for use in a modal. It only accepts one prop, and that’s used to close the modal on click of the button. However, in order to make the modals more accessible and provide a better user experience, it should also be able to close on press of the escape key.

Let’s look at the hook used to make this possible:

useEffect(() => {
window.addEventListener('keydown', handleEscapeKeyDown);
return () => {
window.removeEventListener('keydown', handleEscapeKeyDown);
};
}, []);

useEffect accepts two arguments and doesn’t return anything. The first parameter is a function that holds the code you want to run. If you return a function from this function, it will be used for “clean-up.” This is where you would negate the effects of your effect if you need to. Here I use it to unbind the event listener.

Get Dani Lewandowski’s stories in your inbox

Join Medium for free to get updates from this writer.

The optional second parameter tells React when you want this hook to be called. If you don’t pass anything, your function will be called on mount and every rendered update. If you pass an array of values, like props or values from state, the function will be called on mount and whenever any of those values change. So if you want to trigger an effect purely when one or a few props change, you can! It’s a streamlined way of writing componentDidUpdate with a lot less effort. Or, if you pass an empty array like in the code sample, it will only be called on mount.

Our returned “clean-up” function is called before any repeated call of the effect function, and always on unmount. This is done in order to “ensure consistency by default and prevents bugs that are common in class components due to missing update logic.” (React Hooks docs)

A form with controlled inputs

This example is a very simple form for updating two fields. In order to use controlled inputs and simplify gathering the form data, I’m using useState to store the input values.

Functional components that use useState don’t have access to a single state object like class-based components do. Instead, we use useState for each value we want to store in a state variable.

const [name, setName] = useState(props.name);

useState is a simple function that just accepts one optional argument. If you do pass an argument to useState, that will be the value’s initial state. In the form example, I’m passing the user’s already existing name and e-mail to be the default values.

Calling useState returns an array with two values. The first one is the current value of the state variable, and the second one is a setter function for you to use to update the state as needed. Here we’re using array spreading to easily access them. They can be named whatever you want since array spreading works by index. (If it’s still confusing, the React useState docs explain it well.)

To keep the inputs in the example controlled, I use the setter function on change of the input and pass the state variable as its value:

<input                    
name="name"
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
required
/>

useState is really simple, and will probably be the most used hook. It gets especially fun when you start combining it with other hooks!

Accessing static user data

Getting basic information about who is currently logged in is a great use case for React Context. It’s cumbersome to pass the user prop to every component in our tree, since it rarely changes. With useContext, it works the same and looks a lot neater:

Creating context providers remains the same, but now we don’t need to wrap children in functions to access those values! With useContext it’s as easy as calling a function and using the results of it to access our context values:

const user = useContext(UserContext);

useContext requires only one argument, and it’s the context object of the context you want to access. You can use useContext anywhere as long as it’s within the provider of that context. Even better yet, it will update the returned value whenever your context updates! It’s super helpful for avoiding prop-drilling without the use of libraries like Redux.

If you’re interested in a deeper dive into possible uses for hooks, I strongly recommend

’s talk from React Conf 2018. He spoke after and introduced hooks for the first time. It was overwhelming but immensely exciting:

Hooks are an immensely helpful feature that makes me excited about the future of React. The more you work with them, the more components you start to notice could be simplified with them.

If you want to test hooks, I recommend spinning up an app with Create React App (CRA), bringing over some of your own existing components, and refactoring them with hooks. As you see your components shrink, I think you’ll fall in love with them too.

𝓲 💖 👏’s
If people enjoy this article, I’ll follow up with how I’m organizing custom hooks in projects, how to reuse logic with them, and the power of combining multiple hooks.

Many thanks for the copy-editing by

and Ash Dague!

--

--

codeburst
codeburst

Published in codeburst

Bursts of code to power through your day. Web Development articles, tutorials, and news.

Dani Lewandowski
Dani Lewandowski

Written by Dani Lewandowski

Web Engineer at Spotify, former (and probably future) Engineering Manager.

Responses (5)