Polling vs Websockets (с примерами на React хуках)

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Вступление

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

Polling

Polling – это метод, при котором клиент периодически отправляет запросы на сервер для получения обновленных данных. Этот подход прост в реализации, но может быть неэффективен при частых запросах, так как он увеличивает нагрузку на сервер и сеть.

Untitled
Untitled

Рефетч может происходить при нажатии кнопки, по истечению определенного количества времени, или при любом другом событии.

WebSockets

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

Untitled
Untitled

Клиент отправляет запрос, а сервер возвращает ему handshake, после чего устанавливается websocket соединение, в котором данные моментально приходят от клиента до сервера, и наоборот.

Рассмотрим примеры реализации обоих подходов

Создадим 2 приложения: в первом реализуем чат на основе поллинга, добавим пользователю кнопку “обновить”, на которую будет происходить рефетч; во втором же сделаем чат и установим web socket соединение, для моментального обновления данных.

Зависимости

Для реализации задумки мне пригодится всего 2 библиотеки:

  • shadcn/ui - для красивых ui компонентов

  • reactuse - лучшая утилитарная библиотека с огромным количеством переиспользуемых react хуков (мы возьмем оттуда useQuery и useWebsocket)

Установим зависимости и нужные нам компоненты из ui библиотеки (это начало будет одинаковым для обоих приложений)

$yarn add @siberiacancode/reactuse
$yarn add tailwindcss
$npx tailwindcss init
$npx shadcn-ui@latest init
$npx shadcn-ui@latest add button card input

Для обоих приложений создадим одинаковый компонент чата. Начнем с обычной верстки. Для этого импортируем из shadcn/ui следующие компоненты: button, input, scroll-area, separator. (см. документацию, чтобы посмотреть как добавлять компоненты)

Создадим развертку компонента Chat:

import { Button } from "./ui/button";
import { Card, CardContent, CardTitle } from "./ui/card";
import { Input } from "./ui/input";
import { ScrollArea } from "./ui/scroll-area";
import { Separator } from "./ui/separator";
const Chat = () => {
return (
<Card className=" w-80 h-96">
<CardTitle>
<div className="p-2">Chat</div>
<Separator />
</CardTitle>
<CardContent className="p-0 flex flex-col">
<ScrollArea className=" w-full h-72">
<div className=" p-2">
<div className="flex">
<div className=" bg-slate-300 text-background rounded-md p-1.5 max-w-64 shadow-slate-300 shadow-md">
Message to you
</div>
</div>
<div className="flex justify-end">
<div className=" bg-slate-800 text-foreground rounded-md p-1.5 max-w-64 shadow-slate-800 shadow-md">
Message from you
</div>
</div>
</div>
</ScrollArea>
<div className=" flex ">
<Input placeholder="Your message..." className="" />
<Button className="">Send</Button>
</div>
</CardContent>
</Card>
);
};
export default Chat;

Получим следующий ui:

Untitled
Untitled

Добавим type Message:

type Message = {
  text: string;
  type: "client" | "server";
};

Создадим состояние messages, в котором будем хранить все сообщения:

import { useState } from "react";
const messages = useState<Message[]>([])

Немного поменяем верстку, чтобы в чате отоброжались только сообщения из стэйта messages и на них применялись определенные стили, в соответствии с тем, является ли тип сообщения “server” или “client”

<ScrollArea className=" w-full h-72">
  <div className="p-2">
    {messages.map((message, index) => {
      if (message.type === "client")
        return (
          <div className="flex justify-end" key={index}>
            <div className=" bg-slate-800 text-foreground rounded-md p-1.5 max-w-64 shadow-slate-800 shadow-md">
              {message.text}
            </div>
          </div>
        );
      else
        return (
          <div className="flex">
            <div className=" bg-slate-300 text-background rounded-md p-1.5 max-w-64 shadow-slate-300 shadow-md">
              {message.text}
            </div>
          </div>
        );
    })}
  </div>
</ScrollArea>;

Добавим хук работы с полями ввода

useField - этот хук из пакета reactuse вы можете использовать для удобного взаимодествия с полями ввода.

const messageInput = useField({initialValue: ''})

Здесь мы задали initialValue, равное пустой строке. Далее мы будем обращаться к messageInput, для взаимодействия с полем ввода.

Добавим к нашему инпуту следующее:

<Input placeholder="Your message..." {...messageInput.register()} />

Таким образом мы регистрируем и привязываем хук к этому полю ввода

1 - Метод Polling

Для каждого из способов нам понадобиться создать свой моковый сервер. В случае с polling воспользуюсь библиотекой от создатиля reactuse -

Источник: https://habr.com/ru/articles/833104/


Интересные статьи

Интересные статьи

Всем привет! Меня зовут Егор Молчанов, я разработчик в команде CRM для менеджеров ипотечного кредитования в компании Домклик. Хочу поделиться своим опытом создания VR‑тура с помощь...
Mortal Kombat - Vs Screen (MKX version) Fan art by LukenStruken CC BY-SA 3.0Моя работа состоит в написании кода на React. Несмотря на то, что мне нравится React, при разработке на нем я столкнулся с н...
Привет, Хабр! Представляю вашему вниманию перевод статьи “React SEO: Tips to Build SEO-friendly Web Applications” автора Paridhi Wadhwani.О чем пойдет речьВы узнаете проблемы, с которыми сталкивается...
Разбираемся на практике с тестированием собственных React-хуков с использованием TypeScript и React Testing Library, добиваясь 100% покрытия тестами.
Способов управления состоянием между компонентами в React множество. Из-за простоты автор остановился на React Context, но есть проблема. Если изменить значение одного поля, повторно будут отрисованы ...