• Что бы вступить в ряды "Принятый кодер" Вам нужно:
    Написать 10 полезных сообщений или тем и Получить 10 симпатий.
    Для того кто не хочет терять время,может пожертвовать средства для поддержки сервеса, и вступить в ряды VIP на месяц, дополнительная информация в лс.

  • Пользаватели которые будут спамить, уходят в бан без предупреждения. Спам сообщения определяется администрацией и модератором.

  • Гость, Что бы Вы хотели увидеть на нашем Форуме? Изложить свои идеи и пожелания по улучшению форума Вы можете поделиться с нами здесь. ----> Перейдите сюда
  • Все пользователи не прошедшие проверку электронной почты будут заблокированы. Все вопросы с разблокировкой обращайтесь по адресу электронной почте : info@guardianelinks.com . Не пришло сообщение о проверке или о сбросе также сообщите нам.

Level Up Your Forms with React 19's useActionState Hook

Lomanu4 Оффлайн

Lomanu4

Команда форума
Администратор
Регистрация
1 Мар 2015
Сообщения
1,481
Баллы
155
The Back Story


I've been writing about forms and data management in React for a long time. As many of us know, handling forms in React has always been a pain. You have to manage state, pass it to inputs, handle change events, and then gather all that state to use your form data. Even for something as simple as a text field, you need a state variable and a change handler.

Sure, we've gotten used to this pattern — but honestly, it's a lot more work compared to plain HTML forms.

Enter React 19


Recently, React launched a new stable version that introduced several new hooks. Among the updates, one that stands out is the useActionState hook. And it's a game changer — especially for forms.

With useActionState, you no longer need to manually manage state or write a change handler just to get the value of a text field.

Let’s look at a simple example: a user details form. It has a few input fields, and when the user clicks the submit button, we validate the input and send the data to the server.


export default function Form() {
return (
<div className="form-cont">
<form>
<input
type="text"
placeholder="Username"
name="user"
aria-label="Username"
/>

<input
type="password"
placeholder="Password"
name="password"
aria-label="Password"
/>

<select name="select" defaultValue="">
<option value="" disabled>
-- Select a fruit --
</option>
<option value="banana">Banana</option>
<option value="apple">Apple</option>
<option value="orange">Orange</option>
</select>

<fieldset>
<legend>Choose a fruit (radio)</legend>
<label>
<input type="radio" name="fruit" value="orange" />
Orange
</label>
<label>
<input type="radio" name="fruit" value="apple" />
Apple
</label>
<label>
<input type="radio" name="fruit" value="banana" />
Banana
</label>
</fieldset>

<fieldset>
<legend>Select fruits (checkbox)</legend>
<label>
<input type="checkbox" name="fruits" value="orange" />
Orange
</label>
<label>
<input type="checkbox" name="fruits" value="apple" />
Apple
</label>
<label>
<input type="checkbox" name="fruits" value="banana" />
Banana
</label>
</fieldset>

<button type="submit">Submit</button>
</form>
</div>
);
}

Now, if you want to access the field values, you typically create state and change handlers for each input, like user, select, fruit, and fruits. I know the field names are a bit simplistic, but let's focus on the core idea.

Accessing field values is still manageable, sure — but there's a cost: each state change triggers a re-render. That can add up, especially with large forms.

This is exactly where the useActionState hook shines.

What Is the useActionState Hook?


The useActionState hook in React 19 simplifies form submissions by managing form state updates and server actions together.

No need for useState or manual event handlers anymore.

It takes three parameters:

  • actionFn: A function called when the form is submitted. It takes two arguments:
  1. A previous state
  2. Form data (type FormData)
    • initialState: The initial value for the form state. This is used only before the first submission.
    • formRef (optional): A ref to the form element. Helps automatically collect form data when the form is submitted.
It returns an array with:

  • currentState: The latest form state returned by actionFn
  • action: A function to assign to the form's action attribute (<form action={action} ...>)
  • isPending: A boolean indicating whether the form is currently submitting (great for loading states)
Working Example: Hands-on With useActionState


Now that we've covered how useActionState works, let's put it into practice with a simple form component — the same one we've been using earlier.

Action Function:


export type FormState = {
user: string;
fruit: string;
fruits: string[];
select: string;
};

export const submitForm = (prevState: FormState, formData: FormData): FormState => {
const user = formData.get("user")?.toString() || "";
const fruit = formData.get("fruit")?.toString() || "";
const fruits = formData.getAll("fruits").map(String);
const select = formData.get("select")?.toString() || "";

console.log({ user, fruit, fruits, select });

return {
...prevState,
user,
fruit,
fruits,
select,
};
};
Updated Form Component:


import { useActionState } from "react";
import { submitForm } from "../actions/submitForm";
import type { FormState } from "../actions/submitForm";

export default function Form() {
const [formState, formAction] = useActionState<FormState, FormData>(
submitForm,
{
user: "",
fruit: "",
fruits: [],
select: "",
}
);

return (
<div className="form-cont">
<form action={formAction}>
<input
type="text"
placeholder="user"
name="user"
defaultValue={formState.user}
/>
<select name="select" defaultValue={formState.select}>
<option disabled value="">
--
</option>
<option>Banana</option>
<option>Apple</option>
<option>Orange</option>
</select>

<div>
<label>
<input
type="radio"
name="fruit"
value="orange"
defaultChecked={formState.fruit === "orange"}
/>
Orange
</label>
<label>
<input
type="radio"
name="fruit"
value="apple"
defaultChecked={formState.fruit === "apple"}
/>
Apple
</label>
<label>
<input
type="radio"
name="fruit"
value="banana"
defaultChecked={formState.fruit === "banana"}
/>
Banana
</label>
</div>

<div>
<label>
<input
type="checkbox"
name="fruits"
value="orange"
defaultChecked={formState.fruits.includes("orange")}
/>
Orange
</label>
<label>
<input
type="checkbox"
name="fruits"
value="apple"
defaultChecked={formState.fruits.includes("apple")}
/>
Apple
</label>
<label>
<input
type="checkbox"
name="fruits"
value="banana"
defaultChecked={formState.fruits.includes("banana")}
/>
Banana
</label>
</div>

<button>Submit</button>
</form>
</div>
);
}

Here, we call the useActionState hook with our submitForm action and provide an initial form state. One little but important detail — we add defaultValue and defaultChecked to the inputs. Why? Because when you submit the form, the inputs reset. This helps retain the values after submission. If needed, you could also implement a resetValues function.

A Fully Working Demo



?

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.



About the Author


Bharat has been a Front-End developer since 2011. He has a thing for building great developer experience. He loves learning and teaching all things tech.

Find him on

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

,

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

, and

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

.


Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.




Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

 
Вверх Снизу