Sobes.tech
Middle

Jaka jest funkcja Redux Thunk i czy można się bez niego obejść?

sobes.tech AI

Odpowiedź od AI

Redux Thunk to middleware dla Redux, które pozwala na pisanie twórców akcji zwracających funkcję zamiast zwykłego obiektu akcji.

Ta funkcja otrzymuje argumenty dispatch (do wysyłania innych akcji) i getState (do dostępu do aktualnego stanu magazynu). Akcje thunk są przydatne do wykonywania operacji asynchronicznych, takich jak zapytania do API, przed wysłaniem synchronicznej akcji w celu zaktualizowania stanu.

Bez Redux Thunk (lub podobnego middleware, np. Redux Saga lub Redux Observable), twórcy akcji mogą zwracać tylko obiekty, co uniemożliwia bezpośrednie obsługiwanie operacji asynchronicznych w standardowym Redux.

Można obejść się bez Redux Thunk, korzystając z innych middleware do efektów ubocznych, takich jak:

  • Redux Saga: Używa generatorów do zarządzania operacjami asynchronicznymi, oferując bardziej potężne i testowalne podejście.
  • Redux Observable: Oparte na RxJS, używa Observable do zarządzania asynchronicznymi strumieniami danych.
  • Redux Promise Middleware: Automatycznie obsługuje promisy, dispatchując akcje po ich rozwiązaniu lub odrzuceniu.

Wybór zależy od złożoności logiki asynchronicznej i preferencji zespołu. Dla prostych przypadków Thunk jest zwykle wystarczający i łatwiejszy do nauki. Dla bardziej skomplikowanych scenariuszy Saga lub Observable mogą być bardziej odpowiednie.

Przykład akcji thunk:

// actions/user.js
import axios from 'axios'; // Przykład użycia biblioteki do zapytań

export const FETCH_USER_REQUEST = 'FETCH_USER_REQUEST';
export const FETCH_USER_SUCCESS = 'FETCH_USER_SUCCESS';
export const FETCH_USER_FAILURE = 'FETCH_USER_FAILURE';

// Twórcy akcji synchronicznych
const fetchUserRequest = () => ({
  type: FETCH_USER_REQUEST
});

const fetchUserSuccess = (user) => ({
  type: FETCH_USER_SUCCESS,
  payload: user
});

const fetchUserFailure = (error) => ({
  type: FETCH_USER_FAILURE,
  payload: error
});

// Asynchroniczny twórca akcji thunk
export const fetchUser = (userId) => {
  return async (dispatch, getState) => {
    dispatch(fetchUserRequest()); // Wysyłamy akcję rozpoczęcia zapytania
    try {
      const response = await axios.get(`/api/users/${userId}`); // Wykonujemy asynchroniczne zapytanie
      dispatch(fetchUserSuccess(response.data)); // Wysyłamy akcję sukcesu z danymi
    } catch (error) {
      dispatch(fetchUserFailure(error.message)); // Wysyłamy akcję błędu
    }
  };
};