Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Выразительный React - Прямоугольник и собачка #5168

Merged
merged 11 commits into from Mar 31, 2024
152 changes: 152 additions & 0 deletions recipes/expressive-react-rectangle/index.md
@@ -0,0 +1,152 @@
---
title: "Выразительный React: простые компоненты на сервере"
description: "Создаём простой компонент на React."
authors:
- hellsquirrel
related:
- tools/react-and-alternatives
- tools/web-server
- tools/bundlers
tags:
- article
---

В статье вы познакомитесь с React и создадите первый простой компонент — прямоугольник с собачкой. В этом примере мы не будем запускать код в браузере. Вместо этого напишем простой скрипт, который запустит сервер и отдаст HTML-страницу с компонентом. Эта техника называется рендеринг на стороне сервера (Server-Side Rendering, SSR).

## Что такое React?

React — это библиотека, которая позволяет создавать переиспользуемые кусочки интерфейса – компоненты. Для описания компонента вы используете JavaScript или TypeScript, специальные правила и синтаксис, который называется JSX.

Комбинируя компоненты, вы создаёте свой уникальный React-мир.

<aside>

👀 React можно использовать и без JSX, но это редко бывает нужно. Код React-компонента с использованием JSX легче читать.

</aside>

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

* Создать компонент с помощью JavaScript/TypeScript и JSX.
* Написать код для отображения компонента.
* Преобразовать весь код в понятный браузеру JavaScript (без JSX).
* Подключить преобразованный код к HTML-странице. (как и любой другой JavaScript, используя тег `<script>`).

Однако в этой статье мы сделаем всё по-другому 🙃

* Cоздадим компонент с помощью TypeScript и JSX (тот же самый шаг).
* Напишем скрипт, который запускает сервер и отдает HTML-страницу с нашим компонентом.
* Откроем страницу и полюбуемся результатом.

## Подготовка рабочего места

> Здесь и далее я предполагаю, что вы работаете на macOS. Для Windows и Linux инструкции не должны отличаться, но если у вас вдруг что-то не заведётся, приносите issues.
> Если вы используете Windows, посмотрите в сторону [WSL](https://learn.microsoft.com/en-us/windows/wsl/).

Убедитесь, что у вас установлен Node.js. Если Node.js нет, скачайте его [с официального сайта программной платформы](https://nodejs.org/en/download).

Создайте папку для проекта и перейдите в неё в терминале.

```bash
mkdir -p expressive-react/rectangle
cd expressive-react/rectangle
```

Выполните команду:

```bash
npx bun init
```

<aside>

🥟 Мы будем использовать набор инструментов [из библиотеки Bun](https://bun.sh/docs/bundler). Для других сборщиков команды инициализации и установки дополнительных библиотек отличаются.

</aside>

Булочка создаст все нужные файлы и папки.

Выполните команду:

```bash
npx bun index.ts
```

Полюбуйтесь на «Hello, World!» в консоли.

Теперь установите React.
HellSquirrel marked this conversation as resolved.
Show resolved Hide resolved

```bash
npx bun install react react-dom
```

## Создаём прямоугольник и собачку

Создайте файл _Rectangle.tsx_ с таким содержимым:

```tsx
const Rectangle: FC = () => <div style={{border: "1px solid brown" }}>🐶</div>;

export const rectangleElement = <Rectangle />;
```

В этом файле создаётся React-компонент `Rectangle`. Любой React-компонент — это просто функция, которая возвращает разметку, описанную при помощи JSX.

<aside>

👌 `null` или обычная строка на JavaScript — это тоже валидная JSX-разметка.

</aside>

Затем создадим `React-element`. `React-element` — это то, что может отобразить браузер. Вы можете думать о React-компоненте как о шаблоне, а о `React-element` как о конкретном экземпляре этого шаблона.

Мы экспортировали `React-element`, чтобы переиспользовать его в другом файле.

## Генерируем HTML

Добавим в файл _index.ts_ код, который будет создавать и запускать сервер. В результате работы сервер выдаст HTML-страницу с собачкой в прямоугольнике.

```tsx
import { renderToString } from "react-dom/server";
import { rectangleElement } from './Rectangle';

const html = `
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Собачка в прямоугольнике</title>
</head>
<body>
${renderToString(rectangleElement)}
</body>
</html>`

Bun.serve({
port: 8080,
async fetch() {
return new Response(html, {
headers: {
"Content-Type": "text/html",
}
});
},
});
```

Запускаем сервер командой:

```bash
npx bun index.ts
```

Откройте [http://localhost:8080](http://localhost:8080), и убедитесь, что собачка видна. Если да, то значит всё получилось, а мне не нужно редактировать эту статью 😊

Разберемся что происходит в файле _ndex.ts_. Мы импортировали элемент `rectangleElement` и функцию `renderToString` из библиотеки `react-dom/server`. Эта функция преобразует React-элемент в строку, которую можно вставить в HTML.

## Как это работает?

Мы сделали свой собственный [серверный рендеринг](https://react.dev/reference/react-dom/server) с очень ограниченными возможностями. Например, в текущей реализации мы не можем добавить интерактивности собачке ☹️ Здесь нам это и не нужно, мы разберёмся как оживлять React-миры в другой статье.

Дальше мы создали шаблон HTML-страницы, вставили в него наш прямоугольник и собачку. После этого мы вызвали специальное API из нашего инструментария. [`Bun.serve`](https://bun.sh/docs/api/http) создаёт сервер, который отдаёт нашу HTML-страницу. Чтобы это сделать, мы определили колбэк `fetch`, который возвращает ответ `Response` с нашей страницей.