Урок 1: Введение в React и современный фронтенд

Наконец то дошли руки до React. Это первый урок из нашего большого курса, рассчитанного на 30 подробных занятий. Мы начнем с самого начала, не требуя от вас никаких предварительных знаний о React, только базовое понимание HTML, CSS и JavaScript.

Сегодня мы не будем писать сложный код. Наша главная задача, это заложить прочный фундамент. Мы разберемся, что такое React, почему он стал таким популярным и какие проблемы разработки он решает. Мы поговорим о ключевых концепциях, таких как виртуальный DOM и компонентный подход и сравним разработку на «ванильном» JavaScript с разработкой на React. Поверьте, поняв эти основы, вы будете гораздо легче осваивать практические приемы в следующих уроках.

Что такое React?

Давайте начнем с самого главного вопроса: что же такое React? Если вы искали информацию в интернете, то наверняка встречали сложные формулировки вроде «React это JavaScript-библиотека для создания пользовательских интерфейсов». Звучит солидно, но давайте разберем эту фразу по косточкам, чтобы она стала понятной и простой.

Во-первых, React это именно библиотека, а не фреймворк. Это важное различие. Фреймворк (например, Angular или Vue), это всеобъемлющая структура, которая диктует вам, как должна быть организована ваша программа, как вы должны структурировать папки, как писать код. Он предоставляет готовые решения для маршрутизации, работы с данными и много чего еще. React же более скромен и сфокусирован. Он решает одну конкретную задачу и делает это блестяще. Его задача отрисовывать пользовательский интерфейс (UI) на основе ваших данных. Все остальное (маршрутизация, управление состоянием на высоком уровне) вы можете выбрать на свой вкус и подключить к React отдельно. Это дает гибкость и свободу.

Во-вторых, «для создания пользовательских интерфейсов». Что это значит? Представьте себе любую современную веб-страницу, например, ленту в ВК. Это не статичная страница, как в 90-е. Это динамическое приложение, вы можете лайкать посты, добавлять комментарии, которые появляются мгновенно, пролистывать бесконечную ленту. Все эти интерактивные элементы, кнопки, поля ввода, всплывающие окна, списки и есть пользовательский интерфейс. React предоставляет вам мощные инструменты, чтобы создавать такие интерфейсы легко, быстро и, что самое важное, поддерживаемо.

React был создан в Facebook и впервые выпущен в 2013 году. Он родился из внутренних нужд компании, столкнувшейся с проблемой поддержки огромного и сложного кода своего приложения. Со временем его популярность взлетела до небес и сегодня он является одним из самых востребованных инструментов в индустрии веб-разработки. Но почему? Что в нем такого особенного? Ответ кроется в двух фундаментальных концепциях: виртуальный DOM и компонентный подход. Давайте погрузимся в них.

Виртуальный DOM

Чтобы понять, зачем нужен Виртуальный DOM, давайте сначала вспомним, что такое настоящий, «браузерный» DOM.

Что такое DOM?

DOM (Document Object Model) это программное представление HTML-документа. Когда браузер загружает страницу, он парсит HTML-код и строит из него дерево объектов. Каждый тег (<div><p><button>) становится узлом (нодой) в этом дереве. JavaScript может взаимодействовать с этим деревом, чтобы изменять структуру, стиль и содержимое страницы. Например, вы можете написать document.getElementById('myButton').textContent = 'Новый текст' и кнопка на странице мгновенно обновится.

Проблема в том, что работа с реальным DOM медленная. Каждое изменение, даже самое маленькое, заставляет браузер пересчитывать стили (reflow) и перерисовывать часть страницы (repaint). В простых приложениях это не заметно, но в сложных, динамических интерфейсах (где данные постоянно меняются) прямые манипуляции с DOM через document.querySelector и подобные методы приводят к серьезным проблемам с производительностью. Представьте, что у вас есть список из 100 элементов и вы меняете данные в одном из них. При прямом подходе вам пришлось бы найти в DOM нужный элемент и обновить его. Браузер выполнит перерисовку. А если таких изменений десятки в секунду? Приложение начнет «лагать».

Виртуальный DOM как решение

React решает эту проблему, вводя прослойку между вашим кодом и реальным DOM, виртуальный DOM (VDOM).

Виртуальный DOM это легковесная JavaScript-копия реального DOM. Это просто объект в памяти, который описывает, как должна выглядеть ваша страница. Когда состояние вашего приложения меняется (например, пользователь добавил новый элемент в список), React создает новую версию Виртуального DOM, отражающую эти изменения.

У React есть две версии VDOM, старая (до изменения) и новая (после изменения). Он запускает алгоритм под названием «согласование» (reconciliation), который сравнивает эти два дерева и находит минимальный набор изменений («diff» — разницу) между ними. Это похоже на сравнение двух версий документа в «Режиме правок».

Найдя эти минимальные изменения, React одним пакетом, максимально эффективно, применяет их к настоящему DOM. Браузер выполняет одну операцию по обновлению, вместо множества мелких и неоптимизированных.

Простая аналогия

Представьте, что вам нужно переставить мебель в комнате.

  • Прямая работа с DOM. Вы берете один стул, переносите его, смотрите. Потом берете стол, переносите, смотрите. Потом понимаете, что стол стоит не там и снова его двигаете. Много лишних движений.

  • Работа через Виртуальный DOM. Вы сначала рисуете на плане комнаты (это виртуальный DOM), как будет выглядеть итог. Потом продумываете оптимальный маршрут: сначала вынести все маленькие предметы, потом передвинуть диван, потом занести стол. И только после этого, имея готовый план, вы за один заход выполняете все действия в правильном порядке.

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

Компонентный подход

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

Что такое компонент?

Компонент это независимый, переиспользуемый кусочек кода, который отвечает за одну часть пользовательского интерфейса. Представьте, что вы строите дом не из кирпичей и раствора, а из готовых, стандартизированных блоков Лего. У вас есть блок-окно, блок-дверь, блок-стена. Вы комбинируете их, чтобы построить здание любой сложности.

В мире React такими «блоками» являются компоненты. Например, для сайта интернет-магазина у вас могут быть такие компоненты:

  • Header — шапка с логотипом и меню.

  • ProductCard — карточка товара с изображением, названием, ценой и кнопкой «Купить».

  • SearchBar — строка поиска.

  • UserProfile — виджет профиля пользователя.

Каждый компонент инкапсулирует в себе собственную структуру (HTML), внешний вид (CSS) и логику (JavaScript). Вы создаете их один раз, а потом используете снова и снова, как функции в JavaScript.

Преимущества компонентного подхода:

  1. Повторное использование. Создав компонент Button, вы можете использовать его по всему приложению, просто как тег <Button />. Вам не нужно копировать HTML, CSS и JS для каждой новой кнопки. Хотите изменить стиль всех кнопок? Вы правите один файл компонента Button.

  2. Сопровождаемость. Код организован логично. Если есть баг в отображении карточки товара, вы знаете, что искать нужно в файле ProductCard.js. Не нужно рыться в тысячах строк монолитного кода.

  3. Разделение ответственности. Каждый компонент заботится сам о себе. Компонент SearchBar знает, как обрабатывать ввод пользователя, но не знает и не должен знать, как компонент ProductList отфильтровывает товары. Это делает код чище и предсказуемее.

  4. Масштабируемость. Такой подход идеально подходит для больших проектов, над которыми работает команда разработчиков. Каждый программист может работать над своим набором компонентов, не мешая другим.

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

Сравнение с ванильным JavaScript

Давайте наглядно посмотрим, в чем разница между подходами, на простом примере. Создадим приложение-счетчик, которое имеет кнопку и отображает число, увеличивающееся при каждом клике.

Пример на ванильном JavaScript

html
<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vanilla JS Counter</title>
</head>
<body>
    <div id="app">
        <h1>Счетчик: <span id="counter">0</span></h1>
        <button id="incrementBtn">Увеличить</button>
    </div>

    <script>
        // Находим элементы в DOM
        const counterElement = document.getElementById('counter');
        const buttonElement = document.getElementById('incrementBtn');

        // Создаем переменную для хранения состояния
        let count = 0;

        // Добавляем обработчик события на кнопку
        buttonElement.addEventListener('click', function() {
            // Изменяем состояние
            count++;
            // Вручную обновляем DOM, чтобы отразить новое состояние
            counterElement.textContent = count;
        });
    </script>
</body>
</html>

Что мы здесь делаем?

  1. Вручную ищем элементы в DOM (getElementById).

  2. Вручную управляем состоянием (переменная count).

  3. Вручную «привязываем» логику к DOM, добавляя обработчик события.

  4. Вручную обновляем DOM при каждом изменении состояния.

Это просто для счетчика. Но представьте, что у вас есть форма с десятком полей, каждое из которых должно валидироваться, динамически меняться в зависимости от других полей и все это должно быть отражено в интерфейсе. Код быстро превратится в спагетти, где логика, состояние и манипуляции с DOM переплетаются так, что разобраться в них становится невероятно сложно. Вы постоянно будете думать: «А какой кусок DOM нужно обновить, если изменились вот эти данные?».

Теперь посмотрим на тот же пример в React

Для этого мы воспользуемся онлайн-песочницей CodeSandbox, чтобы не заботиться о настройке окружения (это тема следующего урока).

jsx
// App.js - это наш главный компонент
import React, { useState } from 'react';

function App() {
  // Используем хук useState для управления состоянием.
  // `count` - это текущее значение состояния (0).
  // `setCount` - это функция для его обновления.
  const [count, setCount] = useState(0);

  // Функция-обработчик для клика по кнопке
  const handleIncrement = () => {
    // Вызываем setCount, передав новое значение.
    // React автоматически перерисует компонент с новым значением count.
    setCount(count + 1);
  };

  // Возвращаем JSX - описание того, что должно быть отрисовано.
  return (
    <div>
      <h1>Счетчик: <span>{count}</span></h1>
      <button onClick={handleIncrement}>Увеличить</button>
    </div>
  );
}

export default App;

Что изменилось?

  1. Декларативный подход. Мы не говорим браузеру как обновлять интерфейс («найди элемент span и поменяй его текст»). Мы просто объявляем, как интерфейс должен выглядеть в зависимости от состояния: «Если count равен 5, то покажи <h1>Счетчик: <span>5</span></h1>«. React сам заботится о том, как привести DOM в соответствие с этим описанием. Мы думаем о что, а не о как.

  2. Совместное расположение логики и разметки. Логика (состояние count, функция handleIncrement) и разметка (JSX) находятся в одном месте, внутри компонента App. Это делает компонент самодостаточным и понятным.

  3. Автоматическое управление DOM. Мы не пишем document.getElementById и textContent. Мы просто обновляем состояние через setCount и React, используя механизм Виртуального DOM, сам вычисляет и применяет необходимые изменения к реальному DOM.

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

Практические задачи и примеры кода

Не пугайтесь, если код кажется непонятным, на данном этапе главное уловить общую идею и философию.

Задача 1: Мысленное проектирование компонентов

Посмотрите на главную страницу любого известного вам сайта, например, YouTube или Twitter. Попробуйте мысленно разбить интерфейс на компоненты.

  • Что можно выделить в отдельный переиспользуемый компонент? (Кнопка, карточка видео, твит, строка меню).

  • Как бы вы их назвали? (SidebarVideoPreviewTweetLikeButton).

  • Какие данные должны приходить в эти компоненты извне? (Для VideoPreview это URL изображения, заголовок видео, имя автора).

Это упражнение не требует написания кода, но оно невероятно полезно для развития «компонентного» мышления.

Задача 2: Простой компонент приветствия

Взгляните на код ниже. Это простейший React-компонент. Он не имеет состояния и просто выводит разметку. Такие компоненты называются «статическими» или «презентационными».

jsx
// Greeting.js
import React from 'react';

// Это функциональный компонент. Он просто возвращает JSX.
function Greeting() {
  return <h1>Привет, мир! Добро пожаловать в курс по React!</h1>;
}

export default Greeting;

Что происходит в коде:

  1. Мы импортируем React из библиотеки (это обязательно для файлов с JSX).

  2. Мы объявляем функцию Greeting, которая и является нашим компонентом.

  3. Эта функция возвращает JSX. Синтаксис, очень похожий на HTML, но внутри JavaScript. Он описывает, что мы хотим увидеть на странице.

  4. Мы экспортируем наш компонент, чтобы использовать его в других файлах.

Если бы у нас был главный компонент App, мы могли бы использовать Greeting вот так:

jsx
// App.js
import React from 'react';
import Greeting from './Greeting'; // Импортируем наш компонент

function App() {
  return (
    <div>
      <Greeting /> {/* Вот так мы используем компонент, как тег HTML */}
    </div>
  );
}

export default App;

Обратите внимание, как компонент Greeting используется как самозакрывающийся XML-тег <Greeting />. Это и есть наше «Лего».

Задача 3: Компонент с пропсами (входными данными)

Давайте сделаем наш компонент Greeting более гибким. Что, если мы хотим приветствовать разных пользователей по имени? Мы можем передать имя в компонент, как аргумент в функцию. В React эти «аргументы» называются props (свойства).

jsx
// Greeting.js
import React from 'react';

// Теперь компонент принимает аргумент `props`.
// Мы можем сразу "деструктуризировать" его, чтобы получить `name`.
function Greeting({ name }) {
  // Используем значение `name` внутри JSX, заключив его в фигурные скобки.
  return <h1>Привет, {name}! Рад видеть тебя в курсе!</h1>;
}

export default Greeting;

Теперь, используя этот компонент в App, мы можем передавать ему разные имена:

jsx
// App.js
import React from 'react';
import Greeting from './Greeting';

function App() {
  return (
    <div>
      <Greeting name="Максим" />
      <Greeting name="Анна" />
      <Greeting name="Петр" />
    </div>
  );
}

export default App;

На экране мы увидим:

text
Привет, Максим! Рад видеть тебя в курсе!
Привет, Анна! Рад видеть тебя в курсе!
Привет, Петр! Рад видеть тебя в курсе!

Вот он, принцип повторного использования! Мы создали один компонент, но с разными «пропсами» он отображает разную информацию. Пропсы только для чтения, компонент получает их извне и не может их менять.

Итоги первого урока

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

  • React это JavaScript-библиотека для создания пользовательских интерфейсов. Она фокусируется на своей задаче и дает разработчику свободу выбора остальных инструментов.

  • Виртуальный DOM это техника, которая позволяет React очень эффективно обновлять реальную веб-страницу.

  • Компонентный подход, это методология, при которой интерфейс разбивается на независимые, переиспользуемые части (компоненты). Это делает код организованным, сопровождаемым и масштабируемым.

  • React использует декларативный подход. Мы описываем, как интерфейс должен выглядеть в разных состояниях, а React сам заботится о манипуляциях с DOM. Это противоположность императивному подходу «ванильного» JS, где мы даем браузеру четкие пошаговые инструкции.

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

В следующем уроке мы настроим окружение для разработки, создадим наш первый React-проект с помощью мощного инструмента Create React App и напишем «Hello, World!», который будет работать на вашем компьютере.

До встречи в Уроке 2!

Полный курс с уроками по React для начинающих

Поделиться статьей:
Поддержать автора блога

Поддержка автора осуществляется с помощью специальной формы ниже, предоставленной сервисом «ЮMoney». Все платёжные операции выполняются на защищённой странице сервиса, что обеспечивает их корректность и полную безопасность.

Персональные рекомендации
Оставить комментарий