← Назад к вопросам

Что такое Action?

1.0 Junior🔥 181 комментариев
#JavaScript Core

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Что такое Action?

Action — это концепция, которая используется в различных контекстах Frontend-разработки. Чаще всего она связана с управлением состоянием приложения. Рассмотрим основные значения.

Action в Redux

В Redux Action — это простой JavaScript объект, который описывает, что произошло в приложении:

const action = {
  type: 'USER_LOGGED_IN',
  payload: {
    userId: 123,
    username: 'alice'
  }
};

Ключевые свойства Action:

  • type — обязательное поле, описывает тип события
  • payload — данные, передаваемые с экшеном (опционально)

Workflow с Action

Action используется в цепочке Redux:

// 1. Компонент dispatch-ит action
function LoginButton() {
  const dispatch = useDispatch();

  const handleLogin = () => {
    dispatch({
      type: 'USER_LOGGED_IN',
      payload: { userId: 123, username: 'alice' }
    });
  };

  return <button onClick={handleLogin}>Login</button>;
}

// 2. Reducer получает action и обновляет state
function authReducer(state = {}, action) {
  switch (action.type) {
    case 'USER_LOGGED_IN':
      return { ...state, user: action.payload };
    case 'USER_LOGGED_OUT':
      return { ...state, user: null };
    default:
      return state;
  }
}

Action Creator

Функция, которая создаёт action объект:

// Action Creator
const userLoggedIn = (userId, username) => ({
  type: 'USER_LOGGED_IN',
  payload: { userId, username }
});

const userLoggedOut = () => ({
  type: 'USER_LOGGED_OUT'
});

// Использование
dispatch(userLoggedIn(123, 'alice'));
dispatch(userLoggedOut());

Async Action (Thunk)

Для асинхронных операций используются Thunk Action Creator:

// Thunk
const loginUser = (credentials) => async (dispatch) => {
  dispatch({ type: 'LOGIN_START' });

  try {
    const response = await fetch('/api/login', {
      method: 'POST',
      body: JSON.stringify(credentials)
    });
    const data = await response.json();

    dispatch({
      type: 'LOGIN_SUCCESS',
      payload: data
    });
  } catch (error) {
    dispatch({
      type: 'LOGIN_ERROR',
      payload: error.message
    });
  }
};

// Использование
dispatch(loginUser({ email: 'john@example.com', password: '...' }));

Action в React Context

В Context API + useReducer действия выглядят похоже:

const initialState = { user: null, loading: false };

function authReducer(state, action) {
  switch (action.type) {
    case 'LOGIN_REQUEST':
      return { ...state, loading: true };
    case 'LOGIN_SUCCESS':
      return { ...state, user: action.payload, loading: false };
    case 'LOGIN_ERROR':
      return { ...state, error: action.payload, loading: false };
    default:
      return state;
  }
}

function AuthProvider({ children }) {
  const [state, dispatch] = useReducer(authReducer, initialState);

  const login = async (credentials) => {
    dispatch({ type: 'LOGIN_REQUEST' });
    try {
      const user = await fetchUser(credentials);
      dispatch({ type: 'LOGIN_SUCCESS', payload: user });
    } catch (error) {
      dispatch({ type: 'LOGIN_ERROR', payload: error.message });
    }
  };

  return (
    <AuthContext.Provider value={{ state, login }}>
      {children}
    </AuthContext.Provider>
  );
}

Action в Next.js Server Actions

В Next.js 13+ Server Actions — это функции, выполняемые на сервере:

// app/actions.ts
'use server';

export async function updateUserProfile(formData) {
  const name = formData.get('name');
  const email = formData.get('email');

  const response = await db.users.update({
    name,
    email
  });

  revalidatePath('/profile');
  return response;
}

// app/profile/page.tsx
import { updateUserProfile } from '@/app/actions';

export default function ProfilePage() {
  return (
    <form action={updateUserProfile}>
      <input name="name" />
      <input name="email" />
      <button type="submit">Update</button>
    </form>
  );
}

Action как обработчик событий

В HTML/JavaScript, Action иногда означает функцию-обработчик:

// React
function Button() {
  const handleClick = () => {
    console.log('Button clicked');
  };

  return <button onClick={handleClick}>Click me</button>;
}

// Или в HTML форме
<form onSubmit={(e) => handleSubmit(e)}>
  <input type="text" />
  <button type="submit">Send</button>
</form>

Типизация Action в TypeScript

type Action = 
  | { type: 'USER_LOGGED_IN'; payload: { userId: number; username: string } }
  | { type: 'USER_LOGGED_OUT' }
  | { type: 'SET_LOADING'; payload: boolean };

function reducer(state: State, action: Action): State {
  switch (action.type) {
    case 'USER_LOGGED_IN':
      return { ...state, user: action.payload };
    case 'USER_LOGGED_OUT':
      return { ...state, user: null };
    case 'SET_LOADING':
      return { ...state, loading: action.payload };
  }
}

Best Practices для Action

1. Единственная ответственность

// Плохо — слишком много в одном action
{ type: 'COMPLEX_UPDATE', payload: { user, posts, comments } }

// Хорошо — отдельные действия
{ type: 'UPDATE_USER', payload: user }
{ type: 'UPDATE_POSTS', payload: posts }

2. Нормализованные имена типов

// ✅
'USER_LOADED'
'POST_CREATED'
'COMMENT_DELETED'

// ❌
'load_user'
'createPost'
'delete-comment'

3. Не мутируй state в reducer

// Плохо
state.user.name = 'New Name';

// Хорошо
return { ...state, user: { ...state.user, name: 'New Name' } };

Заключение

Action — это описание события или команда к изменению состояния в приложении. Это концепция, которая используется в:

  • Redux — для управления глобальным состоянием
  • Context API + useReducer — для локального управления состоянием
  • Next.js Server Actions — для выполнения операций на сервере
  • HTML/JavaScript — просто как обработчик события

Понимание Action критично для работы с современным состоянием в React приложениях.

Что такое Action? | PrepBro