Что такое Redux Thunk

Ответ

Redux Thunk — это middleware для Redux, позволяющий обрабатывать асинхронные действия (actions). Он проверяет, является ли action функцией, а не объектом, и если да — вызывает её, передавая dispatch и getState.

Пример:

const fetchData = () => {
  return (dispatch, getState) => {
    dispatch({ type: 'FETCH_START' });
    fetch('/api/data')
      .then(res => res.json())
      .then(data => dispatch({ type: 'FETCH_SUCCESS', payload: data }))
      .catch(err => dispatch({ type: 'FETCH_ERROR', error: err }));
  };
};

// Использование:
dispatch(fetchData());

Когда использовать:

  • Асинхронные запросы (API, таймеры)
  • Условный dispatch (например, проверка состояния перед действием)

Альтернативы: Redux Saga, RTK Query. Thunk прост для базовых сценариев.

Ответ 18+ 🔞

Давай разжую тебе этот Redux Thunk, а то смотрю, глаза стекленеют, как у пьяного удава на рассвете.

Смотри, в обычном Redux экшен — это просто объект, типа «эй, редьюсер, вот тебе данные, делай что хочешь». Но жизнь, сука, сложнее! Иногда надо сначала на сервер сходить, данные вытянуть, а потом уже редьюсеру подсунуть. А он, падла, ждёт объект, а не промис какой-нибудь!

Вот тут-то и выходит на сцену наш герой — Thunk. Это такой прослойщик, middleware, который стоит между твоим dispatch и редьюсером. Его гениальная логика проще пареной репы:

  1. Ты кидаешь в dispatch не объект, а функцию.
  2. Thunk её ловит и такой: «Опа, функция! Ну-ка, давай-ка я тебе сам dispatch и getState в руки суну, работай!».
  3. Ты внутри этой функции делаешь всю свою грязную асинхронную работу: запросы, таймеры, проверки.
  4. А потом, когда всё готово, ты сам, своими руками, диспатчишь нормальные объекты-экшены.

Вот тебе живой пример, чтоб въехал:

// Это не экшен, это функция, которая ВОЗВРАЩАЕТ функцию-экшен. Запутано? Сейчас разберёмся.
const fetchUserData = (userId) => {
  // Вот эту штуку мы и будем диспатчить
  return async (dispatch, getState) => {
    // Сначала говорим миру: "Всё, я начал грузить, все на старт!"
    dispatch({ type: 'USER_FETCH_START' });

    try {
      // Тут асинхронная жесть, которая обычному Redux как серпом по яйцам
      const response = await fetch(`/api/users/${userId}`);
      const data = await response.json();

      // Ура, данные пришли! Диспатчим успех
      dispatch({ type: 'USER_FETCH_SUCCESS', payload: data });
    } catch (error) {
      // Ой, всё! Диспатчим провал
      dispatch({ type: 'USER_FETCH_FAILURE', error: error.message });
    }
  };
};

// Используем как обычно, но диспатчим ФУНКЦИЮ
dispatch(fetchUserData(42));

Когда этот трюк нужен? Да почти всегда, когда твоё приложение не статичная хуйня! Запросы к API, работа с таймерами (setTimeout), чтение из localStorage — везде, где есть хоть капля асинхронности.

А что, есть другие варианты? Ещё бы, ёпта! Это ж программирование, тут на любой чих по три библиотеки.

  • Redux Saga: Это уже не прослойка, а целый эпос. Работает на генераторах, можно выстраивать сложнейшие цепочки, отменять запросы, слушать экшены. Мощно, но учить надо.
  • RTK Query (в составе Redux Toolkit): Вообще, блядь, революция. Он тебе и запросы делает, и кеширует, и инвалидирует, и состояние само в стор кладёт. Для работы с API — просто песня, а не инструмент.

Итог: Thunk — это как швейцарский нож для простых асинхронных дел. Не надо городить огород, если тебе просто данные с бэка получить. Но если твоё приложение превращается в франкенштейна с кучей побочных эффектов — присмотрись к Saga или сразу беги в объятия RTK Query, не ошибёшься.