Sibling State with React Hooks
Tags: javascript, react, webdev, productivity
Published: 2020-09-09 19:59:04

---
title: Sibling State with React Hooks
published: true
description: Lifting state is a great pattern to understand in React. This post walks you through an example stey-by-step.
tags: javascript, react, webdev, productivity
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/3gyximl05fvbwq6kvof1.png
canonical_url: https://laurieontech.com/posts/sibling-state/
---

I was working on an app the other day using React Hooks and I happened upon a pattern I wanted to write up!

## The App

Let's set the scene. I have an `App` with two components, `Box` and `Warning.` The goal is to show the warning when a user "touches" the box that says `Don't touch me!`.

Our initial code looks like this. At the moment, the Warning always appears.
{% codesandbox share-state-step-0-90wig view=split %}

## Detecting Motion

The first thing to do is note when someone mouses over the `Box` component. If we can't detect that action then we can't do anything else. We'll use the `onMouseOver` event and have it print a message to our console to make sure it's working.

If we toggle the console open and mouse over the box we should see a message.

{% codesandbox share-state-step-1-2jl08 view=split %}

## Keyboard Accessible

But not everyone uses a mouse. A user may also focus on the element via keyboard. The `Box` component is a single `div` which is not a tabbable element. To make it tabbable we can set `tabIndex` to `0`. `tabIndex` takes three possible values, `-1` which removes the element from tab order, `0` which adds it, and a positive value which allows you to explicitly set the tab order of the elements on the page.

The second thing we need to add is an `onFocus` event. This looks exactly like our `onMouseOver` event but it's the event that is fired when a keyboard user tabs over to an element.

{% codesandbox share-state-step-15-2gql4 view=split %}

## State hook

Now that we can react to both a mouse or keyboard event, we'll want to somehow send that information to our `Warning` component. This is where React hooks come into play!

In this example, we're going to leverage `useState`. The syntax looks like this.

```jsx
const [value, setValue] = useState("initial value")
```

In our app, we want a boolean value that will tell us whether or not to display the warning. So we create `isDanger` which comes along with `setIsDanger`, a setter function. We'll initialize `isDanger` to `false`.

As it turns out, we can pass this setter function to `Box`. And when we use it, it will alter the value of `isDanger`.

{% codesandbox share-state-step-2-qo9de view=split %}

Note that `isDanger` is initialized in the parent component, `App`. So even though the child component, `Box`, triggered the value change, the state is still tied to `App`. 

We can add a `console.log(isDanger)` line in `App` to confirm this behavior.

## Using state

Now we can pass `isDanger` to our `Warning` component with full confidence that it will change value when we need it to. We'll use `isDanger` to conditionally render the warning message. Otherwise, return `null`.

For accessibility, we'll add the role of `alert` to the div. This means that whenever it appears on screen a screen reader will announce it.

{% codesandbox share-state-step-3-u06z1 view=split %}

## "Resetting" state

And that's our example! If we want to make it a bit better we can change the events we're listening to. In our previous version, we set `isDanger` to true and the warning shows up. However, the warning stays because we never set `isDanger` back to false.

To handle the mouse interaction we can use `mouseEnter` and `mouseLeave`. For the keyboard, we want `onFocus` and `onBlur`. The great part about this is it doesn't change the complexity of our hook and passing state. We just reference the `setIsDanger` function a few additional times.

{% codesandbox share-state-step-4-fk9q8 view=split %}

## Hooks are fun!

This is a [common pattern](https://reactjs.org/docs/lifting-state-up.html) for using state hooks. And it isn't always easy to distill these into digestible examples! So I was very excited to be able to break down this one.