Промежуточное программное обеспечение React: мост между API и компонентами

Промежуточное программное обеспечение не является новым концептом в веб-разработке. Обычно это ассоциируется с бэкенд-фреймворками, такими как Express.js, где присутствует много аутентификации, ведения журналов и т. д. Благодаря своим преимуществам, промежуточное программное обеспечение получило значительное распространение во фронтенде.

Фронтенд-фреймворки, такие как React, внедряют его как способ обработки сложных функций во время управления состоянием. В этом руководстве мы рассмотрим концепцию промежуточного программного обеспечения в React и как его использовать для улучшения функциональности вашего приложения на React и эффективного управления потоком приложения.

К концу вы сможете хорошо понять, что такое промежуточное программное обеспечение в React и как его реализовать с помощью Redux Thunk.

Упрощенное применение промежуточного программного обеспечения в React: оптимизация логики приложения

Что такое промежуточное программное обеспечение?

Как следует из названия, промежуточное программное обеспечение является слоем, который находится между различными компонентами приложения. Он предоставляет слой обработки и функциональности там, где это не было бы возможно без него. Промежуточное программное обеспечение работает путем перехвата запросов, передвигающихся от одного компонента к другому, и позволяет выполнять определенные действия. После выполнения он передает измененный запрос следующему промежуточному программному обеспечению или его предназначенному месту назначения.

Это концепция, преимущественно используемая в бэкенде. Но, как уже упоминалось, она была адаптирована в React для служения аналогичной цели. Теперь давайте подробнее рассмотрим, что означает промежуточное программное обеспечение, в частности в React.

Промежуточное программное обеспечение в React

В React middleware реализуется в виде серии функций, выполняемых одна за другой в том порядке, в котором вы их определяете. Каждая функция имеет доступ к состоянию и действиям приложения. Следовательно, функции могут изменять и отправлять новые действия.

Когда состояние изменяется в React, приложение отправляет действия, которые затем обрабатываются Reducer(ами). Затем Reducer(ы) возвращают новое состояние, которое затем сохраняется и передается обратно в приложение.

Middleware React располагается между отправленным действием и перехватывает его до того, как оно достигнет Reducer’а. Затем он позволяет вам встроиться в этот процесс и выполнить некоторый код над этим действием, например, залогировать его или выполнить вызов API.

После этого он передаст измененное действие в Reducer (если в цепочке нет другого middleware).

Примеры Middleware в React

Вы можете найти Middleware React в основном в Redux, сложной библиотеке управления состоянием React. Redux имеет два основных типа Middleware:

  • Thunk – мы более подробно рассмотрим, как использовать это Middleware для модификации действия.
  • Saga.

Каждый из них обрабатывает различные типы модификаций действий, как мы увидим ниже, когда рассмотрим применение Middleware в React. Другие библиотеки React, такие как React Query, также используют Middleware (более подробно об этом позже).

Прежде чем мы рассмотрим, как это реализовать, давайте изучим различные способы использования Middleware в React.

Использование Middleware в React

Промежуточное ПО React пригодится в следующих случаях:

Отладка и ведение журнала

Промежуточное ПО React можно использовать для ведения журнала информации, такой как текущее состояние, действия и другие данные во время разработки приложения. Более того, это может быть полезным для выявления потенциальных ошибок и неполадок для их раннего устранения.

Регистратор Redux (для Redux) может помочь вам в этом. Он регистрирует действия Redux и изменения состояния для удобной отладки. Он перехватывает каждое отправленное действие и регистрирует предыдущее состояние, действие и следующее состояние.

Авторизация и аутентификация

Если вы хотите аутентифицировать пользователей перед обновлением состояния, вы можете использовать Redux Thunk или Saga для обработки рабочих процессов аутентификации. После того как вы перехватите действие, это промежуточное ПО позволяет вам сохранять токены, проверять аутентификацию перед отправкой действия или обновлять токены.

Другими словами, это промежуточное ПО полезно для проверки, аутентифицирован ли пользователь для доступа к определенному маршруту или нет.

Операции на основе событий

Редуктор React предназначен для выполнения синхронного кода. Это означает, что если вы попытаетесь запустить что-то асинхронное на нем, это не сработает. С использованием промежуточного ПО React, такого как Redux Thunk, вы можете перехватить действие, выполнить асинхронные задачи, например, сделать вызов API, и продолжить к редуктору, как только это будет сделано.

Кэширование данных

React Query (другой промежуточный слой React) может служить эффективным инструментом для кэширования данных приложения. Он автоматически кэширует ответы API и перепроверяет их при необходимости. В результате он помогает избежать избыточных вызовов API, проверяя необходимую информацию в кэше.

Улучшение производительности

Промежуточный слой React также может помочь улучшить производительность приложения, откладывая ненужные действия на потом, дебаунсинг событий и пакетную обработку определенных задач. Кэшируя ответы API, React Query также повышает производительность ваших приложений React.

Как использовать промежуточный слой в React?

Redux – это мощный инструмент для управления глобальным состоянием в приложениях React. Он включает несколько промежуточных слоев в свой набор инструментов, которые можно использовать для добавления пользовательской функциональности в ваши приложения React. Одним из наиболее распространенных является Redux Thunk.

Введение в Redux Thunk

Прежде чем погрузиться в реализацию Thunk, давайте соберем некоторую информацию о нем, чтобы мы могли использовать его эффективно.

Что такое Thunk?

В общем программировании “Thunk” – это просто функция, которая используется для отложенной оценки и выполнения функции. Мы можем рассматривать ее как функцию, откладывающую действие до определенного условия.

В Redux thunk – это конкретная функция, используемая с промежуточным слоем Redux Thunk. Redux Thunk предназначен для выполнения асинхронных операций в вашем приложении React. Ранее мы упомянули, что Reducer создан для выполнения синхронного кода. Это означает, что при диспетчеризации действия редьюсер сразу же обновляет состояние.

Redux Thunk как промежуточное ПО

Redux Thunk действует как промежуточное ПО. Он позволяет создавать action creators, которые возвращают функции (thunks), а не простые объекты действий. Эти функции могут содержать асинхронную логику. Когда вы диспетчеризуете thunk, промежуточное ПО Thunk перехватывает его и выполняет функцию.

Внутри thunk вы можете выполнять свою асинхронную операцию (например, сделать вызов API) и затем диспетчеризовать обычные действия для обновления хранилища Redux, когда операция завершается.

Примечание: Redux Thunk позволяет выполнять как асинхронные, так и синхронные операции, хотя его основная цель – облегчить асинхронные действия. Он не препятствует вам диспетчеризовать синхронные действия; он просто предоставляет механизм для обработки также асинхронных.

С этим разобрались, давайте посмотрим, как работает промежуточное ПО React, реализуя Redux Thunk.

Пошаговое руководство по реализации Redux Thunk

Реализация промежуточного ПО Redux включает следующие шаги:

Шаг 1: Настройка Redux с Thunk

Создайте приложение React и установите зависимости.

Plain Text

 

npx create-react-app newApp

Шаг 2: Установка Redux Thunk

Запустите следующую команду для установки Redux Thunk.

Plain Text

 

npm install redux-thunk

Шаг 3: Включение промежуточного ПО Thunk

JavaScript

 

Enable the Thunk middleware in the Redux store.

import { configureStore } from '@reduxjs/toolkit';
import thunk from 'redux-thunk';
import rootReducer from './reducers'; // Combine all reducers here

const store = configureStore({
reducer: rootReducer,
middleware: [thunk],
});

export default store;

Примечание: При использовании Redux Toolkit нет необходимости устанавливать thunk явно.

Шаг 4: Написание асинхронной функции

Thunk возвращает другую функцию, которая получает аргументы dispatch и getstate для чтения состояния или отправки действий. Приведен пример кода для получения данных:

JavaScript

 

// Типы действий
const START_FETCH = 'START_FETCH';
const FETCH_SUCCESS = 'FETCH_SUCCESS';
const FETCH_ERROR = 'FETCH_ERROR';

  // Создатели действий
const startFetch = () => ({ type: START_FETCH });
const fetchSuccess = (data) => ({ type: FETCH_SUCCESS, payload: data });
const fetchError = (error) => ({ type: FETCH_ERROR, payload: error });

  // Thunk-действие
export const fetchData = () => {
return async (dispatch, getState) => {
      dispatch(startFetch()); // Notify that the fetch has started

try {
const response = await fetch('https://jsonplaceholder.typicode.com/posts');
if (!response.ok) {
throw new Error('Failed to fetch data');
}
const data = await response.json();

        dispatch(fetchSuccess(data)); // Send the fetched data to the store
} catch (error) {
         dispatch(fetchError(error.message)); // Handle any errors
}
};
  };

Шаг 5: Обработка отправленных действий в редюсере

Обрабатывайте отправленные действия, обновляя редюсер.

JavaScript

 

const initialState = {
data: [],
    isLoading: false,
    error: null,
};

export const dataReducer = (state = initialState, action) => {
switch (action.type) {
case START_FETCH:
return { ...state, isLoading: true, error: null };
case FETCH_SUCCESS:
return { ...state, isLoading: false, data: action.payload };
case FETCH_ERROR:
return { ...state, isLoading: false, error: action.payload };
default:
return state;
}
  };

Шаг 6: Отправка Thunk из компонента

Используйте хук useDispatch для отправки thunk’ов в проектах React.

JavaScript

 

import React, { useEffect } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { fetchData } from './actions';

const DataComponent = () => {
const dispatch = useDispatch();
const { data, isLoading, error } = useSelector((state) => state.data);

useEffect(() => {
      dispatch(fetchData()); // Trigger the thunk to fetch data
}, [dispatch]);

if (isLoading) return <p>Loading...</p>;
if (error) return <p>Error: {error}</p>;

return (
<ul>
{data.map((item) => (
<li key={item.id}>{item.title}</li>
))}
</ul>
);
};

export default DataComponent;

Использование createAsyncThunk

Redux Toolkit содержит встроенный API, который определяет высокоуровневую логику для асинхронных функций, отправляет их и оперативно обрабатывает ошибки. Обратите внимание, что поскольку это предоставляет абстракцию для конкретных случаев использования асинхронных функций, createAsyncThunk не применим ко всем случаям использования thunk’ов. 

Приведен пример реализации createAsyncThunk:

JavaScript

 

import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';

export const dataFetch = createAsyncThunk('data/fetchData', async () => {
const response = await fetch('https://api.example.com/data');
return response.json();
});

const dataSlice = createSlice({
    name: 'data',
    initial_State: { data: [], loading: false, error: null },
extraReducers: (builder) => {
builder
.addCase(dataFetch.pending, (state) => {
          state.loading = true;
          state.error = null;
})
.addCase(dataFetch.fulfilled, (state, action) => {
          state.loading = false;
state.data = action.payload;
})
.addCase(dataFetch.rejected, (state, action) => {
          state.loading = false;
state.error = action.error.message;
});
},
});

export default dataSlice.reducer;

Теперь, чтобы отправить thunk dataFetch, используйте следующий код:

JavaScript

 

dispatch(dataFetch ());

Применение промежуточного программного обеспечения React – Redux Thunk

Thunk’и могут использоваться для различных целей, включая, но не ограничиваясь:

  • Абстрагирование сложной логики от компонентов. 
  • Выполнение асинхронных запросов и логики. 
  • Написание функций для отправки нескольких действий в последовательности.

Middleware React в других библиотеках управления состоянием

Redux – не единственная библиотека React, которая использует промежуточное ПО. Вы можете также найти его в других библиотеках управления состоянием, хотя реализация этой концепции в этих библиотеках отличается от того, как это делается в Redux.

MobX

У MobX нет традиционного промежуточного ПО, как у Redux. Он предлагает аналогичные функции с помощью механизмов, таких как перехватчики, наблюдатели и реакции. Эти механизмы позволяют вам наблюдать изменения в вашем состоянии MobX и реагировать на них. Таким образом, MobX предоставляет способы обработки побочных эффектов, ведения журнала и других задач, с которыми промежуточное ПО обычно справляется в Redux.

Recoil

Recoil не поддерживает промежуточное ПО таким же образом, как Redux, потому что ему это не нужно. Он позволяет вам напрямую обновлять куски состояния (атомы) с использованием определенных функций. Нет диспетчеризации действий к редюсеру, которые можно перехватить с помощью промежуточного ПО. Для обработки асинхронных операций он использует селекторы – производное состояние, зависящее от атомов или других селекторов.

Zustand

Он помогает управлять состояниями с помощью простого API и поддерживает нативное промежуточное ПО для ведения журнала и хранения состояний, так же как и Redux.

XState

XState поддерживает поведение, похожее на промежуточное ПО, с использованием хуков, таких как onTransition, actions, и services. Эти хуки помогают перехватывать и изменять переходы состояний.

Заключение

Промежуточное программное обеспечение действует как мост для соединения и объединения различных компонентов веб-приложения для лучшего потока данных и обработки. Они широко используются на серверной стороне с момента появления, но теперь также нашли применение на клиентской стороне.

В React существует различные способы реализации промежуточного программного обеспечения. Обычно они связаны с библиотеками управления состоянием, такими как Redux и MobX. Самое часто используемое промежуточное ПО React, Thunk, включено в библиотеку Redux. Thunk представляет собой блок кода, выполняющий отложенные задачи.

В этой статье мы рассмотрели промежуточное программное обеспечение в React, библиотеку Redux и Redux Thunk. Мы также рассмотрели шаги по реализации промежуточного программного обеспечения Redux Thunk для получения данных и отправки действий.

Source:
https://dzone.com/articles/demystifying-react-middleware-bridging-apis-and-co