State management with Unstated Next
Tags: react
Published: 2020-05-20 17:01:33

---
title: State management with Unstated Next
published: true
date: 2020-05-01 13:00:34 UTC
tags: react
canonical_url: https://blog.logrocket.com/state-management-with-unstated-next/
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/1iswvmrq1jimmkay9l34.jpeg
---
**Written by [Abdulazeez Abdulazeez Adeshina](https://blog.logrocket.com/author/abdulazeezadeshina/)**✏️

State is a foundational part of React applications, which means managing state is hugely important. Since the introduction of the Context API and then Hooks, managing state has been relatively easy since the Context API helps save us the stress of using Redux.

As a result, multiple state management libraries have been published to further facilitate state management with the Context API, and in this article, I’ll be looking into [Unstated](https://github.com/jamiebuilds/unstated-next) [N](https://github.com/jamiebuilds/unstated-next)[ext](https://github.com/jamiebuilds/unstated-next).

## What is Unstated Next?

Unstated Next is a library built on React’s Context API that allows the sharing of state globally in our applications. Unstated Next has simple API methods, which can be used either as Hooks or component methods. In the subsequent sections, I’ll discuss the API methods and then build a simple demo to demonstrate how Unstated Next works.

Unstated Next can be installed from either Yarn or npm:

```jsx
yarn add unstated-next 

// or

npm install unstated-next
```

## What problems does Unstated Next solve ?

Since Unstated Next is built on the Context API, it solves the same problems that the Context API solves. Unstated Next allows us to:

- Access parent state from child components
- Avoid prop drilling

If you are not familiar with the Context API, it is advisable to [read this article](https://dev.to/bnevilleoneill/what-s-new-in-ember-octane-59do-temp-slug-1121322) before proceeding.

[![LogRocket Free Trial Banner](https://i0.wp.com/blog.logrocket.com/wp-content/uploads/2017/03/f760c-1gpjapknnuyhu8esa3z0jga.png?resize=1200%2C280&ssl=1)](https://logrocket.com/signup/)

## Unstated Next API methods

Unstated Next houses three API methods, and I’ll discuss each one briefly:

### `createContainer(ourHook)`

The `createContainer` method is used to initialize context and takes as an argument the Hook whose state is to be shared globally. This context is traditionally assigned to a variable, as shown below:

```jsx
import { createContainer } from 'unstated-next'

function ourHook() {}

let ourContext = createContainer(ourHook)
// ourContext == {Provider, useContainer}
```

The variable, in turn, returns a provider and `useContainer` method. The `useContainer` method can also be referred to as the consumer.

### Provider method

The provider method, which is appended to the context, takes in an optional initial value to be rendered on the application’s first render and accepts a child component to be rendered. Here’s an example of its usage:

```jsx
import { createContainer } from 'unstated-next'

...

function Component() {}

<OurContainer>
  <Component />
</Ourcontainer>

<OurContainer initialState={"initial value"} />
  <Component />
</Ourcontainer>
```

### `useContainer(ctx)`

The `useContainer(ctx)` Hook takes in the context variable as an argument and is stored in a variable that will be used to access the global state. The `useContainer(ctx)` Hook is used in the component where state is to be accessed — in this case, the child component. This will be demonstrated in the next section.

```jsx
import { useContainer } from "unstated-next"

function ChildComponent() {
  let activity = useContainer(OurContainer)
  return <input value={activity.value} onChange={activity.onChange} />
}
```

The above are the available API methods in the Unstated Next libraries, which are purely built on the React API. In the next section, I’ll be building a simple to-do app to demonstrate how the methods work.

## Setup

Before we dive in too deep, let’s map out the project structure and the installation of the dependencies needed for our to-do app. We’ll start by creating our project folder.

```jsx
mkdir unstated-todo-app && cd unstated-todo-app
mkdir public src src/components
cd public && touch index.html style.css
cd ../src && touch index.js
cd components && touch Todos.js
```

Next, we’ll initialize the directory and install the dependencies needed.

```jsx
npm init -y
npm i react react-dom react-scripts unstated-next
```

Now it’s time to write the `App` rendering component in the `index.js` file.

### `index.js`

This file houses the component responsible for rendering our `Todo``s` component. First, I’ll import the dependencies needed:

```jsx
import React from "react";
import { render } from "react-dom";
import TodoList from "./Components/Todos";
```

Don’t fret, the `TodoList` component will be built after this. Next, we tell React to render our app on the div node with an identifier `"root"`:

```jsx
function App() {
  return (
    <>
      <h3> Unstated Todo App </h3>
      <hr />
      <TodoList />
    </>
  )
}

render(<App />, document.getElementById("root"))
```

Next, we’ll begin writing the `Todo``s` component.

### `Todos.js`

The `Todos` component comprises a custom Hook which will be handling the state for our to-do app alongside some state methods and a component that lets us add and renders our to-do.

We’ll start off by creating our custom hook and initializing with two state objects:

```jsx
import React, { useState } from "react";

function useTodos(initialstate = [{todo: "Test todo"}]) {
  let [todos, setTodo] = useState(initialstate)
  let [todo, setTodoItem] = useState("")
```

Our Hook `useTodos()` takes an initial to-do (which is optional) that is rendered when the app is loaded. It has two state objects: `todos` and `todo`. The `todos` state object is an array of all the to-dos in our app, while the `todo` state object is the to-do added to the `todos` array and has an initial value of an empty string.

The `todo` is set from the user input and then added to the `todos` array by means of a `setTodo()` method, which we’ll be looking at next.

```jsx
  ...
  const handleInput = e => {
    setTodoItem(e.target.value)
  }

  const addTodo = e => {
    e.preventDefault()
    setTodo([...todos, {todo}])
    setTodoItem("")
  }

  const removeTodo = id => {
    const todoList = todos.filter(todo => todo.todo !== id)
    return setTodo(todoList)
  }

  return { todos, todo, addTodo, removeTodo, handleInput }

}
```

1. The `handleInput()` method is used to set the `todo` state to the value the user inputs in the form by using the `setTodoItem` state handler.
2. The `addTodo()` method adds the to-do item into the `todos` array by means of the `setTodo([...todos, todo])` method. It then sets the `todo` state to an empty string.
3. The `removeTodo()` method removes a to-do from the `todos` array.

Then, we return the values of the state and the Hook’s method so it can be accessible in our components.

Next, we’ll create a container from our `useTodo()` Hook. First, we’ll import the `createContainer` Hook from Unstated Next:

```jsx
// After the react import
import { createContainer } from "unstated-next";
```

Then we create the container that will be used in our components. It gives us direct access to our app’s state and its method, as discussed in the previous section:

```jsx
let Todos = createContainer(useTodos)
```

The container doesn’t do anything yet, and we haven’t built the components for the to-do. You guessed right — we’ll be building that next.

```jsx
function Todo({ todo }) {
  let todosContainer = Todos.useContainer()
  return (
    <>     
      <ul className="w3-ul w3-card-4">
        <li key={todo.todo} className="w3-display-container" >
           {todo.todo}
           <span className="w3-button w3-transparent w3-display-right" onClick={() => todosContainer.removeTodo(todo.todo)}>&times;</span>
        </li>
      </ul>
    </>
  )
}
```

The component above is responsible for rendering the `todo` passed as a prop from an iteration of the `todos` array.

Next, we build the consumer component that displays the to-dos and let us add a to-do:

```jsx
function DisplayTodos() {  
  let todosContainer = Todos.useContainer()
  return (
    <React.Fragment>
      <input type="text" className="w3-input w3-border w3-round" placeholder="Write an article" value={todosContainer.todo} onChange={todosContainer.handleInput} />
      <button onClick={todosContainer.addTodo} className="w3-button w3-round w3-black">Add Todo</button>
      <hr />
      {
        todosContainer.todos.map(todo => (
          <Todo todo={todo} />
        ))
      }
    </React.Fragment>
  )
}
```

On lines 8–12, we iterate over the `todos` array state and then pass each `todo` as a prop to the `Todo` component.

In the components above, the container is used from the variable `todosContainer` to allow access to the states and its methods, as can be seen in the render blocks of each component.

Next, we define a component that renders the consumer component `DisplayTodos()` under the context provider since nothing can be consumed without a provider.🙂

```jsx
export default function TodoList() {
  return (
    <Todos.Provider>
      <DisplayTodos />
    </Todos.Provider>
  )
}
```

We make the component a default export since it has been imported to be rendered in the `App` component.

## Running our app

With the completion of our app’s build process, we are yet to write the code for the `index.html` and `style.css` files. Let’s do that before we proceed:

### `index.html`

```jsx
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
  <link rel="stylesheet" href="style.css" type="text/css">
  <title>Unstated-next Recipe App</title>
</head>
<body>
  <div id="root" class="w3-container"></div>
</body>
</html>
```

### `style.css`

```jsx
body {
  font-family: 'Gill Sans', 'Gill Sans MT', Calibri, 'Trebuchet MS', sans-serif;
  background-color: antiquewhite;
}
```

After that, let’s configure `package.json` so we can run our app. Under the `scripts` section, replace the code there with:

```jsx
"start": "react-scripts start"
```

With that done, let’s start the app and view it live on [`http://localhost:3000`](http://localhost:3000/):

```jsx
npm run start
```

Here’s a demonstration of the app in use:

![Our To-do App In Action](https://i1.wp.com/blog.logrocket.com/wp-content/uploads/2020/05/to-do-app-demo.gif?resize=600%2C375&ssl=1)

## Conclusion

This article should give you a basic understanding of what Unstated Next is, its features, and how it works. The main takeaway is that you can use Unstated Next in place of the traditional React Context API Hooks and Redux.

Unstated Next is an excellent React library for managing state apps. However, be aware that there are cases in which the Context API, and thus Unstated Next, shouldn’t be used. Read about them in [this article](https://dev.to/bnevilleoneill/pitfalls-of-overusing-react-context-if5). The code used in this article can be found on [GitHub](http://unstated-next-todo).

* * * 
## Full visibility into production React apps 

Debugging React applications can be difficult, especially when users experience issues that are difficult to reproduce. If you’re interested in monitoring and tracking Redux state, automatically surfacing JavaScript errors, and tracking slow network requests and component load time, [try LogRocket.](https://www2.logrocket.com/react-performance-monitoring)

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/eq752g8qhbffxt3hp9t4.png)

[LogRocket](https://www2.logrocket.com/react-performance-monitoring) is like a DVR for web apps, recording literally everything that happens on your React app. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred. LogRocket also monitors your app's performance, reporting with metrics like client CPU load, client memory usage, and more.

The LogRocket Redux middleware package adds an extra layer of visibility into your user sessions. LogRocket logs all actions and state from your Redux stores.

Modernize how you debug your React apps — [start monitoring for free.](https://www2.logrocket.com/react-performance-monitoring)
* * *

The post [State management with Unstated Next](https://blog.logrocket.com/state-management-with-unstated-next/) appeared first on [LogRocket Blog](https://blog.logrocket.com).