What is useActionState in React ?
Tags: react, webdev, javascript
Published: 2024-07-03 10:33:51

`useActionState` is a hook that allows you to update state based on the result of a form action.

> It's currently only available in React’s Canary and experimental channels. In addition, you need to use a framework that supports React Server Components to get the full benefit of useActionState.

It simplifies managing form state updates based on server-side actions. It's particularly useful with React Server Components (RSC) for faster response times.

### 📝 Basic example

The most simple example to understand the concept would be that of a form that increments a counter. 

```javascript
import { useActionState } from "react";

async function increment(previousState, formData) {
  return previousState + 1;
}

function StatefulForm({}) {
  const [state, actionToTake] = useActionState(increment, 0);
  return (
    <form>
      {state}
      <button formAction={actionToTake}>Increment</button>
    </form>
  )
}
```

As you can see the form takes two arguments
 - An action function that handles form submission and interacts with the server.
 - An initialState object representing the initial form state.
- The action function itself will receive two arguments - previousState and the formData. In the first call the previousState will be the initialState that would have been initialized when useActionState was called.

And it returns an array containing
 - The current form state object
 - a `actionToTake` (you can rename it to whatever makes most sense - see example below) function that you can use as a button `formAction` handler (example above) or `action` handler in form component itself (example below).

> 💡 When `<form>` is rendered by a Server Component, and a Server Action is passed to the `<form>`’s action prop, the form is progressively enhanced. This means that forms can be submitted before the JavaScript bundle is loaded 🔥

### 📝 Example with server actions

Another interesting property the hook returns is the `isPending` property which can help handle loading states.

```js
// actions.js
'use server'

export default async function incrementLike(prevState, data) {
  // Simulate delay
  return new Promise((resolve, reject) =>
    setTimeout(() => resolve(prevState + 1), 3000)
  )
}
```

```js
//like.js
'use client'

import incrementLike from './actions'
import { useActionState } from 'react'

function LikeButton() {
  const [likes, likeCountAction, isPending] = useActionState(incrementLike, 0)

  return (
    <>
      <p>Total Likes: {likes}</p>
      <form action={likeCountAction}>
        <button
          type='submit'
          disabled={isPending}
          className="border box-shadow bg-[#fff] p-4 disabled:opacity-50 disabled:cursor-not-allowed"
        >
          Like
        </button>
      </form>
    </>
  )
}
```
### 📝 Key Takeaways

- `useActionState` simplifies managing form state based on server-side actions.
- It's particularly useful with React Server Components (RSC) for faster response times.
- It offers functionalities like isPending to handle loading states during server interactions.

### 📝 Things to Keep in Mind
- `useActionState` is currently experimental and might change in future releases.
- You need a framework that supports React Server Components to utilize the full potential of this hook.

Happy coding!