Больше не нужно искать работу мечты — присоединяйтесь к команде Клауда

Оптимизация запросов к серверу с помощью React Hooks

Мария Богомаз
Мария Богомаз
Технический писатель
31 июля 2024 г.
123
15 минут чтения
Средний рейтинг статьи: 5

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

React Hooks — это функции из библиотеки React, которые позволяют взаимодействовать с функциональными компонентами, включая управление состоянием, контекстом, жизненным циклом и прочими аспектами. С появлением React Hooks разработчики получили эффективный и универсальный инструмент для настройки взаимодействия с сервером, что ет возможность точно определять время и частоту сетевых запросов. 

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

Для того, чтобы выполнять все шаги, описанные в этом руководстве, вам понадобятся следующие умения и инструменты:

  • Знание основ JavaScript и умение создавать React-приложение с нуля

  • Понимание основ React Hooks

  • Навыки выполнения серверных запросов в JavaScript

  • Наличие рабочей среды для разработки 

  • Редактор кода

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

Создание нового проекта на React

Прежде чем мы погрузимся в мир разработки приложения на React, важно начать с основного шага — создания нового проекта. Этот начальный этап задает основу для всей последующей разработки, и правильная настройка проекта может существенно упростить процесс создания и поддержания кода в дальнейшем. React, будучи одной из самых популярных библиотек для создания пользовательских интерфейсов, предлагает множество инструментов и шаблонов для ускорения и упрощения начальной стадии разработки. Используя современные инструменты и подходы, такие как Create React App (CRA), вы можете быстро создать стабильную и готовую к работе базу, позволяющую сосредоточиться на написании функционала вместо настройки окружения. 

Перед тем как начать работу над проектом, убедитесь, что на вашем компьютере установлены все обязательные компоненты для работы с React, в частности Node.js и npm. Если они еще не установлены, их можно загрузить с официального сайта. После установки этих инструментов, откройте терминал или командную строку, перейдите в директорию, где вы хотите создать свое приложение, и воспользуйтесь инструкциями ниже в зависимости от того, с каким инструментом вы предпочитаете работать: Create React App или Vite.

Create React App

Выполните следующую команду для инициализации нового проекта на React:

npx create-react-app timeweb-cloud-app

Замените timeweb-cloud-app на настоящее имя вашего проекта. Эта команда загрузит все необходимые зависимости и создаст типовой проект, готовый для разработки.

Если приложение успешно создано, то консоль отобразит следующий вывод:

Success! Created timeweb-cloud-app at your_file_path/timeweb-cloud-app
Inside that directory, you can run several commands:

npm start
Starts the development server.

npm run build
Bundles the app into static files for production.

npm test
Starts the test runner.

npm run eject
Removes this tool and copies build dependencies, configuration files and scripts into the app directory. If you do this, you can’t go back!

We suggest that you begin by typing:

cd timeweb-cloud-app
npm start

Happy hacking!

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

cd timeweb-cloud-app

Затем выполните следующую команду, согласно приветственному сообщению, которая должна запустить сервер разработки:

npm start

Если все сделано правильно, сервер запустится, на экране будет отображен следующий вывод:

Compiled successfully!

You can now view timeweb-cloud-app in the browser

http://localhost:3000

Note that the development build is not optimized.
To create a production build, use npm run build.

Это откроет ваше новое React-приложение в браузере по умолчанию. Вы должны увидеть загрузочный экран React:

Image1

Теперь можно переходить к работе с хуками — в файле App.js, размещенному по пути /timeweb-cloud-app/src/.

Vite

Выполните следующую команду для инициализации нового проекта на React:

npm create vite@latest timeweb-cloud-app

Замените timeweb-cloud-app на настоящее имя вашего проекта. Эта команда загрузит все необходимые зависимости и создаст типовой проект, готовый для разработки.

При запросе на установку Vite нажмите -y, чтобы подтвердить.

Выберите тип приложения — React.

После завершения процесса настройки перейдите в только что созданную директорию, выполнив команду ниже:

cd timeweb-cloud-app

И выполните следующие команды, чтобы запустить сервер разработки:

npm install
npm run dev

Если все сделано правильно, сервер запустится, на экране будет отображен адрес вашего приложения, например, http://localhost:5173.

Скопируйте адрес из консоли и вставьте в строку браузера. Вы должны увидеть приветственный экран React.

Теперь можно переходить к работе с хуками — в файле App.jsx, размещенному по пути /timeweb-cloud-app/src/.

Синхронизация компонентов с помощью хука useEffect

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

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

Рассмотрим пример использования хука useEffect для получения данных из API JSON Placeholder и обновление состояния компонента.

Перейдите в файл App.jsApp.jsx внутри папки src вашего проекта, удалите стандартный код и замените его приведенным ниже примером:

import React, { useEffect, useState } from 'react';

function MyComponent() {
  const [data, setData] = useState([]);

  useEffect(() => {
    async function fetchData() {
      const response = await fetch('https://jsonplaceholder.typicode.com/posts');
      const data = await response.json();
      setData(data);
    }
    fetchData();
  }, []);

  return (
    <div>
      {data.map((item) => (
        <div key={item.id}>
          <h2>- {item.title}</h2>
          <p>{item.body}</p>
        </div>
      ))}
    </div>
  );
}

export default MyComponent;

После импорта стандартных хуков и объявления функционального компонента, мы используем хук useState для создания состояния data, а также функцию setData, которая будет использоваться для обновления этого состояния. Начальное состояние — пустой массив, така как мы ожидаем список данных. Хук useEffect здесь выполняет асинхронный запрос к API при первом рендеринге компонента, при помощи функции fetchData. Дальше при помощи метода .map мы отображаем каждый элемент из обновленного состояния data в виде отдельных компонентов. Каждый элемент содержит заголовок и тело. Мы назначаем item.id в качестве уникального ключа для каждого <div>, чтобы React мог эффективно идентифицировать и управлять этими компонентами в DOM. Наконец, мы экспортируем компонент MyComponent, чтобы его можно было использовать в других частях приложения. 

Если вы обновите браузер или приложение, вы сможете увидеть результат запроса в соответствии с образом кода выше:

Image3

Важным аспектом является минимизация ненужным повторных рендеров, которые могут негативно сказаться на производительности. 

Корректная обработка ошибок при выполнении серверных запросов также критически важна для избежания сбоев в компоненте. Обработка ошибок может быть выполнена путем добавления блока try-catch внутри функции fetchData и использование хука setError для обновления состояния компонента с сообщением об ошибке. Таким образом, приложение сможет отобразить сообщение об ошибке пользователю, если что-то пойдет не так.

vds

Оптимизация производительности серверных запросов с помощью хука useMemo

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

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

Рассмотрим пример использования хука useMemo для мемоизации данных из API JSON Placeholder и обновления состояния компонента. Замените код в файле App.jsApp.jsx на следующий фрагмент кода:

import { useEffect, useState, useMemo } from 'react';

function MyComponent({ postId }) {
  const [data, setData] = useState({});
  useEffect(() => {
    async function fetchData() {
      const response = await fetch(`https://jsonplaceholder.typicode.com/posts/1`);
      const data = await response.json();
      setData(data);
    }
    fetchData();
  }, [postId]);

  const title = useMemo(() => data.title, [data]);

  return (
    <div>
      <h2>{title}</h2>
    </div>
  );
}

export default MyComponent

Первым делом мы импортируем хуки useEffect, useState и useMemo для управления состоянием. Мы используем useState для создания состояния data и функции setData для его обновления. Начальное состояние — пустой объект, который позже будет содержать информацию о посте, загруженную с сервера. С помощью функции fetchData мы делаем запрос к API, в массив зависимостей передаем параметр postId. Это означает, что эффект будет выполнен только тогда, когда postId изменится. Внутри компонента мы используем хук useMemo для мемоизации заголовка, передавая data.title в качестве первого аргумента и [data] в качестве второго аргумента, чтобы обновляться при изменении данных. Далее идут действия аналогичные примеру useEffect выше.

Image5

Важно отметить, что useMemo не всегда необходим и должен использоваться только тогда, когда компонент зависит от пропсов или состояния, которые могут часто изменяться, а вычисление значения является дорогостоящим. Неправильное использование useMemo может привести к утечкам памяти и другим проблемам производительности. 

Управление состоянием серверных запросов с помощью хука useReducer

Хук useReducer в React аналогичен хуку useState, но предоставляет более сложный и предсказуемый способ управления состоянием. Вместо того чтобы обновлять состояние напрямую, useReducer позволяет вам отправлять действия (actions), которые описывают обновление состояния, и функцию-редьюсер (reducer function), которая обновляет состояние на основе отправленного действия. 

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

Чтобы попробовать этот метод с использованием хука useReducer для мемоизации данных из API JSON Placeholder и обновления состояния компонента, замените код в файле App.jsApp.jsx на следующий фрагмент кода:

import { useReducer } from 'react';

const initialState = { data: [], loading: false, error: '' };
const reducer = (state, action) => {
  switch (action.type) {
    case 'FETCH_DATA_REQUEST':
      return { ...state, loading: true };
    case 'FETCH_DATA_SUCCESS':
      return { ...state, data: action.payload, loading: false };
    case 'FETCH_DATA_FAILURE':
      return { ...state, error: action.payload, loading: false };
    default:
      return state;
  }
};

function MyComponent() {
  const [state, dispatch] = useReducer(reducer, initialState);

  const fetchData = async () => {
    dispatch({ type: 'FETCH_DATA_REQUEST' });
    try {
      const response = await fetch('https://jsonplaceholder.typicode.com/posts');
      const data = await response.json();
      dispatch({ type: 'FETCH_DATA_SUCCESS', payload: data });
    } catch (error) {
      dispatch({ type: 'FETCH_DATA_FAILURE', payload: error.message });
    }
  };

  return (
    <div>
      {state.loading ? (
        <p>Загрузка...</p>
      ) : state.error ? (
        <p>{state.error}</p>
      ) : (
        <div>
          {state.data.map((item) => (
            <div key={item.id}>
              <h2>{item.title}</h2>
              <p>{item.body}</p>
            </div>
          ))}
        </div>
      )}
      <button onClick={fetchData}>Загрузить данные</button>
    </div>   ); } export default MyComponent;

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

Image2

При нажатии на кнопку «Загрузить данные» срабатывает функция fetchData, отвечающая за отправку действий в зависимости от результата запроса: успешного завершения или ошибки.

Image4

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

Разворачивайте приложения на VDS/VPS в Timeweb Cloud

Заключение

В этом руководстве рассмотрены основы оптимизации серверных запросов с помощью React Hooks. Оптимизация запросов к серверу — это непременное условие для повышения производительности и удобства использования вашего веб-приложения. В этой статье мы рассмотрели основные приемы оптимизации запросов:

  • Кэширование результатов с помощью useMemo

  • Централизованное управление состоянием запросов с помощью useReducer

  • Эффективное использование useEffect для выполнения асинхронных операций, зависящих от параметров состояний вашего компонента 

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

  • useContext — этот хук позволяет получить доступ к контексту, созданному с использованием React.createContext. Он дает возможность передавать информацию между компонентами в иерархии без необходимости присваивать пропсы на каждом уровне.

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

  • useRef — данный хук возвращает объект, содержащий свойство .current. Он предназначен для сохранения любого значения, которое должно остаться неизменным между перерисовками компонента.

  • useImperativeHandle — используется вместе с React.forwardRef для настройки значения инстанса, которое присваивается родительскому компоненту при использовании рефа. 

  • useLayoutEffect — аналогичен рассмотренному useEffect, но вызывается синхронно после всех изменений DOM. Полезен, когда нужно измерять и изменять DOM сразу после рендера.

Эти хуки также предоставляют мощные инструменты для управления состоянием и поведением компонентов в React, каждый со своим уникальным случаем применения и особенностями.

Хотите внести свой вклад?
Участвуйте в нашей контент-программе за
вознаграждение или запросите нужную вам инструкцию
img-server
31 июля 2024 г.
123
15 минут чтения
Средний рейтинг статьи: 5
Комментарии 2
Friendly
19.08.2024, 02:48

Пожалуйста, перепишите статью на Vite. create-react-app давно устарел и депрекейтед

Timeweb Cloud
Timeweb Cloud
30.09.2024, 08:08

Здравствуйте!

Create React App по-прежнему остается популярным выбором для создания новых React-проектов благодаря своей простой структуре и готовому к использованию конфигу, что помогает многим разработчикам быстро начинать работу без необходимости настраивать сложные конфигурации вручную. На данный момент, CRA все еще актуален и применяется многими разработчиками для создания новых React-проектов.

Но мы обновили статью, чтобы она была применима и к Vite 👌