State Management in React With Valtio
Tags: react, valtio, statemanagement
Published: 2023-05-03 00:16:26

by [Opeyemi Adepoju](https://blog.openreplay.com/authors/opeyemi-adepoju)

<blockquote><em>State management for React is an important issue, and it can be challenging to decide which of the libraries to use since there are the correct times and places to apply each. Valtio offers a simple, performant, and flexible solution that is well-suited to many projects, and this article will tell you all about it.</em></blockquote>

One tool used for state management is [Valtio](https://valtio.pmnd.rs/), which uses proxies to provide a mutation-style API. [`Proxy`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy) classes serve as an interface to another object. In its broadest sense, a proxy "wraps" the object, and to access the object, one has to pass through the proxy so, the proxy can do additional operations before returning the object. We can proxy almost anything. In the following sections, we'll show how to use Valtio with React, and you'll see it's an easy way of working.

## Why Choose Valtio as a state manager in React

Valtio is a lightweight and intuitive state management library for React that offers several benefits over other state managers, including:

-   **Minimalistic API:** Valtio has a simple and easy-to-learn API, making it less cumbersome than other state managers.
-   **Reactive updates:** Valtio uses Proxies to create reactive updates, meaning that state changes are reflected automatically in the UI.
-   **Performance:** Valtio has a small footprint and is highly performant, making it an ideal choice for projects that require high performance.
-   **Server-side rendering support:** Valtio has built-in support for server-side rendering, which means that your app will smoothly work whether running on the client or the server.
-   **Flexible data structures:** Valtio supports flexible data structures, such as maps and sets, making it easier to work with complex data.
-   **Easy integration:** Valtio can easily integrate with other libraries and tools, like React and TypeScript.


## Getting Started
We will start by creating a new React application.


```
npx create-react-app simple-state-with-valtio
```

Next, we install Valtio.

```
yarn add valtio
```

Then we import the `proxy` and `useProxy` functions from Valtio into our app. 

```javascript
import { proxy, useProxy } from "valtio";
```

Our React component uses the `useProxy` function to create a local snapshot that tracks changes while the `proxy` function creates a new proxy state.


## Components State
Components are a user interface's building blocks that encapsulate a UI logic and can be reused throughout an application. A component can represent a small UI element like a button or a more complex UI element like a form or a modal. They are JavaScript functions or classes that return a React element, which describes what should be rendered on the screen (React element is a lightweight description of what to render, consisting of a type, props, and children)

Valtio has to be a part of the React lifecycle to segregate component states for reuse. You can wrap a proxy in a ref, passing it with props or context. We will discuss how to do this in the outline that follows.

Here is a demonstration of how Valtio lives in the component state:


```jsx
import { proxy, useSnapshot } from "valtio";

/** use context to pass password state */
const PasswordButtonContext = React.createContext(undefined);
const PasswordGeneratorStateProvider = ({
  children,
  numbers,
  length,
  symbols,
}) => {
  const state = React.useRef(
    proxy(new PasswordState({ numbers, length, symbols }))
  ).current;
  return (
    <PasswordButtonContext.Provider value={state}>
      {children}
    </PasswordButtonContext.Provider>
  );
};
// wrap in a custom hook for ease of use
function usePasswordGeneratorState() {
  const passwordState = React.useContext(PasswordButtonContext);
  const snapshot = useSnapshot<PasswordState>(passwordState);
  return { passwordState, snapshot };
}

export default App;
```

**OUTPUT**
   
![-](https://blog.openreplay.com/images/state-management-in-react-with-valtio/images/F1YkwpA.gif)
   
We created a `PasswordButtonContext` using the `React.createContext` function. This context then provides the state of the password generator using the `PasswordGeneratorStateProvider` component. Finally, the `usePasswordGeneratorState` hook lets us access the password generator state and its snapshot. Here is the [link to the complete code on GitHub](https://github.com/SuperRennie/Valtio-component-state-demonstration).

   
**Note** [`useRef`](https://beta.reactjs.org/reference/react/useRef) is a React hook that allows us to create a mutable variable that persists between renders of a component. It returns an object with a single property, `current`, that holds the current value of the reference. It is used when we need to modify a value without causing a re-render of the component.
   
 [`useContext`](https://beta.reactjs.org/reference/react/useContext) is a React hook that allows you to access data and functions from a parent component's context object. It is often used to simplify data management and make data sharing between components more efficient.

A full explanation of the features of Valtio to use in manipulation states is discussed below.

<div style="background-color:#efefef; border-radius:8px; padding:10px; display:block;">
<hr/>
<h3><em>Session Replay for Developers</em></h3> 
<p><em>Uncover frustrations, understand bugs and fix slowdowns like never before with <strong><a href="https://github.com/openreplay/openreplay" target="_blank">OpenReplay</a></strong> — an open-source session replay suite for developers. It can be <strong>self-hosted</strong> in minutes, giving you complete control over your customer data.</em></p>
<img alt="OpenReplay" style="margin-top:5px; margin-bottom:5px;" width="768" height="400" src="https://raw.githubusercontent.com/openreplay/openreplay/main/static/openreplay-git-hero.svg" class="astro-UXNKDZ4E" loading="lazy" decoding="async">
<p><em>Happy debugging! <a href="https://openreplay.com" target="_blank">Try using OpenReplay today.</a></em><p>
<hr/>
</div>


## Proxy and useProxy
In the components state, the `proxy` tracks change to the original object and all nested objects, notifying listeners when an object is modified.

```jsx
import { proxy } from 'valtio'
    
const state = proxy({ count: 0, text: 'hello' })
```


The `useProxy` is a hook provided by the Valtio library that allows you to create a reactive binding to a Valtio proxy object in your React components, making it easy to read and update the state in a performant and scalable way.

When `useProxy` is used with a Valtio proxy object, it returns a reactive state object that automatically updates when the original `proxy` object changes. This functionality shows you can use the returned `state` object to read the current state of the proxy object, and any changes you make to the `state` object will automatically reflect in the UI.
Here's an example of how you can use `useProxy` with a Valtio `proxy` object:

```jsx
import { proxy, useProxy } from "valtio";

const state = proxy({
  count: 0,
  text: "",
});

function Counter() {
  const proxyState = useProxy(state);
  return (
    <div>
      <p>Count: {proxyState.count}</p>
      <button onClick={() => ++state.count}>Increment</button>
    </div>
  );
}

export default function App() {
  return (
    <>
      <Counter />
    </>
  );
}
```
![-](https://blog.openreplay.com/images/state-management-in-react-with-valtio/images/Bcd6KZ4.gif)


In this example, we define a Valtio proxy object called `state` with a `count` and a `text` property. We then use the `useProxy` hook to create a reactive binding to the `state` object, which we store in the `proxyState` variable. Finally, we use the `proxyState` object to display the current count value in the UI and to update the count value when the button is clicked.

Using `useProxy`, we can create a reactive binding to the `state` object that ensures that our UI is always up-to-date with the latest state values and that changes to the state are always reflected in the UI.


## Snapshot and useSnapshot
One of the critical features of Valtio is the `snapshot` and `useSnapshot` functions.

The `snapshot` function creates a read-only copy of your state in the component. It is useful when you want to pass the current state of your application to a component or a function without allowing it to modify the state directly. The `snapshot` function returns a plain JavaScript object that represents the current state of your application.

Here is an example of using `snapshot` in Valtio:

```jsx
import { proxy, snapshot } from "valtio";

const state = proxy({
  count: 0,
});

console.log(snapshot(state)); // { count: 0 }
```

The `useSnapshot` function creates a React hook that allows you to access the current state of your application in a component. It is similar to the `useContext` hook but only updates the component when the state depends on changes.

Here is an example of using `useSnapshot` in Valtio

```jsx
import React from "react";
import { proxy, useSnapshot } from "valtio";

const state = proxy({
  count: 0,
});

function Counter() {
  const snap = useSnapshot(state);
  return (
    <div>
      {snap.count}
      <button onClick={() => ++state.count}>+1</button>
    </div>
  );
}

export default function App() {
  return (
    <>
      <Counter />
    </>
  );
}
```
![-](https://blog.openreplay.com/images/state-management-in-react-with-valtio/images/OQVHtfP.gif)


In this example, the `useSnapshot` hook returns a read-only snapshot of the state, which is used to render the `count` component. The state object is updated when the `increment` button clicks, triggering a `counter` component re-render.

## Conclusion
A typical modern app requires state info management, making Valtio a powerful tool since it is straightforward and robust. Moreover, it combines the potential of proxies in React.js and JavaScript to simplify and modify state data. Here is a [GitHub repository](https://github.com/pmndrs/valtio) for managing states in Valtio. You can also check the [Valtio documentary](https://valtio.pmnd.rs/) for other related API lean to the library.