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
146 changes: 146 additions & 0 deletions recipes/expressive-react-rectangle/index.md
@@ -0,0 +1,146 @@
---
title: "Выразительный React: простые компоненты на сервере"
description: "Создаем простой компонент на React."
HellSquirrel marked this conversation as resolved.
Show resolved Hide resolved
authors:
- hellsquirrel
related:
- tools/react-and-alternatives
- tools/web-server
- tools/bundlers
tags:
- article
---

В статье вы познакомитесь с React и создадите первый простой компонент — прямоугольник с собачкой. В этом примере мы не будем запускать код в браузере. Вместо этого напишем простой скрипт, который запустит сервер и отдаст HTML-страницу с компонентом. Эта техника называется Server Side Rendering.
HellSquirrel marked this conversation as resolved.
Show resolved Hide resolved

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

React это библиотека, которая позволяет создавать переиспользуемые кусочки интерфейса – компоненты. Для описания компонента вы используете JavaScript или TypeScript, специальные правила и синтаксис, который называется JSX.
HellSquirrel marked this conversation as resolved.
Show resolved Hide resolved

Комбинируя компоненты вы создаете свой уникальный React-мир.
HellSquirrel marked this conversation as resolved.
Show resolved Hide resolved

<aside>
React можно использовать и без JSX - но это редко бывает нужно. Код React-компонента с использванием JSX читать значительно легче.
</aside>
HellSquirrel marked this conversation as resolved.
Show resolved Hide resolved

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

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

Однако в этой статье мы сделаем по-другому 🙃
* Cоздадим компонент с помощью TypeScript и JSX. (тот же самый шаг)
* Напишем скрипт, который запускает сервер и отдает HTML-страницу с нашим компонентом.
* Откроем страницу и полюбуемся на результатом.
HellSquirrel marked this conversation as resolved.
Show resolved Hide resolved

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

> Здесь и далее я предполагаю что вы работаете на Mac. Для Windows и Linux инструкции не должны отличаться, но если у вас вдруг что-то не заведется приносите issues.

Убедитесь что у вас установлен Node.js. Если Node.js нет, скачайте его с [официального сайта](https://nodejs.org/en/download).
HellSquirrel marked this conversation as resolved.
Show resolved Hide resolved

Создайте папку для проекта и перейдите в нее в терминале.
HellSquirrel marked this conversation as resolved.
Show resolved Hide resolved

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

Выполните команду
HellSquirrel marked this conversation as resolved.
Show resolved Hide resolved
```bash
npx bun init
```
<aside>
Мы будем использовать набор инструментов из библиотеки [`bun`](https://bun.sh/docs/bundler). Для других сборщиков команды инициализации и установки дополнительных библиотек будут отличаться.
</aside>
HellSquirrel marked this conversation as resolved.
Show resolved Hide resolved

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

Выполните команду
```bash
npx bun index.ts
```

Полюбуйтесь на "Hello, World!" в консоли.
HellSquirrel marked this conversation as resolved.
Show resolved Hide resolved

Теперь установите React.
HellSquirrel marked this conversation as resolved.
Show resolved Hide resolved
```bash
npx bun install react react-dom
```

## Создаем прямоугольник и собачку
Создайте файл _Rectangle.tsx_ с таким содержимым:
HellSquirrel marked this conversation as resolved.
Show resolved Hide resolved

```tsx
const Rectangle: FC = () => <div>🐶</div>;

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

В этом файле оздаётся React-компонент `Rectangle`. Любой React-компонент это просто функция, которая возвращает разметку, описанную при помощи JSX.
HellSquirrel marked this conversation as resolved.
Show resolved Hide resolved

<aside>

👌 `null` или обычная строка на JavaScript это тоже валидная JSX разметка.
HellSquirrel marked this conversation as resolved.
Show resolved Hide resolved

</aside>

Затем мы создали `React-element`. `React-element` это то что может отобразить браузер. Вы можете думать о React-компоненте как о шаблоне, а о `React-element` как о конкретном экземпляре этого шаблона.
HellSquirrel marked this conversation as resolved.
Show resolved Hide resolved

Мы экспортировали React-element, чтобы переиспользовать его в другом файле.
HellSquirrel marked this conversation as resolved.
Show resolved Hide resolved

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

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

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

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

Bun.serve({
port: 8080,
async fetch() {
return new Response(html, {
headers: {
"Content-Type": "text/html",
}
});
},
});
HellSquirrel marked this conversation as resolved.
Show resolved Hide resolved
```

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

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

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


Разберемся что просходит в файле `index.ts`:
Мы импортировали элемент `rectangleElement` функцию `renderToString` из библиотеки `react-dom/server`. Эта функция преобразует React-элемент в строку, которую можно вставить в HTML.
HellSquirrel marked this conversation as resolved.
Show resolved Hide resolved


## Как это работает?
HellSquirrel marked this conversation as resolved.
Show resolved Hide resolved

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

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