useActionState у світі React: Управління діями та станом компонентів.

useActionState у світі React

React — це популярна бібліотека для створення інтерфейсів користувача, яка надає розробникам гнучкість у роботі зі станом та діями компонентів. Одним із сучасних підходів до управління станом є використання спеціальних хуків, таких як useState, useReducer і useContext. Але інколи виникає потреба створити більш гнучкий механізм для управління станом і діями. У таких випадках з’являється концепція “useActionState”.

У цій статті ми розглянемо, що таке useActionState, як він допомагає ефективніше управляти станом у React-додатках, і як його використовувати для оптимізації компонентів. Хоча useActionState не є вбудованим хуком React, ми покажемо, як його реалізувати і застосовувати.

Що таке useActionState?

useActionState — це паттерн або кастомний хук, який об’єднує логіку управління станом та діями в одному місці. Замість того, щоб окремо працювати з useState для стану та вручну створювати функції для обробки дій, useActionState дозволяє:

  1. Описувати стан і дії разом.
  2. Забезпечувати кращу читабельність і масштабованість коду.
  3. Уникати розпорошення логіки між різними хуками або компонентами.

Як це працює?

useActionState базується на принципах хуків React, таких як useReducer. Основна ідея — створити механізм, де стан і функції-обробники взаємодіють через простий API.

Простий приклад виглядає так:

const useActionState = (initialState, actions) => {
  const [state, setState] = React.useState(initialState);

  const boundActions = {};
  for (const key in actions) {
    boundActions[key] = (...args) => {
      const result = actions[key](state, ...args);
      setState(result);
    };
  }

  return [state, boundActions];
};

Як створити useActionState?

Розглянемо реалізацію useActionState на прикладі.

Крок 1: Опис початкового стану та дій

const initialState = {
  count: 0,
};

const actions = {
  increment: (state, amount = 1) => ({ count: state.count + amount }),
  decrement: (state, amount = 1) => ({ count: state.count - amount }),
  reset: () => ({ count: 0 }),
};

Крок 2: Використання кастомного хуку у компоненті

const Counter = () => {
  const [state, actions] = useActionState(initialState, actions);

  return (
    <div>
      <h1>Count: {state.count}</h1>
      <button onClick={() => actions.increment(1)}>Increment</button>
      <button onClick={() => actions.decrement(1)}>Decrement</button>
      <button onClick={actions.reset}>Reset</button>
    </div>
  );
};

У цьому прикладі ми:

  1. Використовуємо useActionState для керування станом лічильника.
  2. Описуємо логіку дій (increment, decrement, reset) в одному об’єкті actions.
  3. Передаємо ці дії разом зі станом у компонент.

Переваги використання useActionState

1. Краща структура коду

Використовуючи useActionState, ви тримаєте стан і логіку його змін разом. Це дозволяє уникати дублювання коду й полегшує підтримку.

2. Масштабованість

Якщо ваш додаток зростає, ви можете легко додати нові дії без необхідності змінювати основний хук чи логику компонентів.

3. Легкість тестування

Ви можете окремо тестувати функції дій, які визначені у об’єкті actions. Це знижує кількість помилок при внесенні змін.

Порівняння useActionState з useReducer

useReducer — це вбудований хук React, який також дозволяє управляти складним станом через редюсери. Однак useActionState надає більш зрозумілий і декларативний підхід для управління простими станами та діями.

Характеристика useReducer useActionState
Складність API Вимагає створення редюсера та dispatch-функцій Простий об’єкт дій
Читабельність Менш зрозумілий для новачків Інтуїтивно зрозумілий
Гнучкість Підходить для складних станів Оптимальний для простих та середніх станів

Використання у реальних проєктах

useActionState найкраще підходить для:

  1. Малих і середніх додатків:
    • Де немає потреби у складних глобальних станах, як-от Redux чи Context API.
  2. Форм:
    • Управління станом полів введення, помилок і валідації.
  3. Компонентів з локальним станом:
    • Наприклад, модальних вікон або вкладок.

Приклад використання у формі:

const formActions = {
  updateField: (state, field, value) => ({
    ...state,
    [field]: value,
  }),
  resetForm: () => ({ name: '', email: '' }),
};

const Form = () => {
  const [formState, formHandlers] = useActionState({ name: '', email: '' }, formActions);

  return (
    <form>
      <input
        type="text"
        value={formState.name}
        onChange={(e) => formHandlers.updateField('name', e.target.value)}
      />
      <input
        type="email"
        value={formState.email}
        onChange={(e) => formHandlers.updateField('email', e.target.value)}
      />
      <button type="button" onClick={formHandlers.resetForm}>Reset</button>
    </form>
  );
};

Висновок

useActionState — це гнучкий підхід до управління станом у React, який поєднує простоту та функціональність. Завдяки йому ви можете уникати зайвого дублювання коду та створювати більш підтримувані й масштабовані додатки.

Він не замінює існуючі інструменти, такі як useReducer чи Redux, але стає чудовим вибором для роботи з локальним станом у компонентах. Спробуйте впровадити цей паттерн у своїх проєктах, щоб зробити їх більш зрозумілими та ефективними.