React Junior
207 subscribers
37 photos
462 links
Изучение React с нуля
加入频道
Изучение документации - не самый популярный у программистов способ начать работу с новым инструментом 😄 Но почему бы и не попробовать. Тем более, у React как будто очень хорошая документация:

👉 https://reactjs.org/ - официальный сайт (англ.)
👉 https://ru.reactjs.org/ - официальный перевод на русский

#ссылки #документация
Подключение React

Есть несколько способов подключить React в проект.

👉 Самый простой - через CDN

Отличный вариант для начала, чтобы попробовать-поиграться с новым инструментом. Просто создал страницу, подключил пару тегов script и начал работу.
все ссылочки - здесь https://reactjs.org/docs/cdn-links.html
есть и develop, и production версии

👉 Чуть сложнее - create-react-app

create-react-app это инструмент для разворачивания проекта на React с нуля. Сначала нужно установить npm-пакет, а затем запустить команду в консоли. Опять же хороший вариант для обучения, чтобы не заморачиваться с настройкой среды, а также для создания новых проектов, не отягощенных старым кодом.

Инструкции здесь: https://github.com/facebook/create-react-app

👉 Для продвинутых - Собрать собственную среду разработки

Потребуется подключить собственно React (npm-пакет: https://www.npmjs.com/package/react) и настроить компиляцию JSX с помощью плагинов Babel.

👉 Песочница

А можно ничего никуда не подключать, а пойти на https://codepen.io/ (или https://codesandbox.io/) и поиграть прямо там.

#началоработы #подключение #документация
👍1
Hello, world!

Любой навык закрепляется практикой, а любая практика начинается с Hello, world!

https://codepen.io/furrycat/pen/VwprQLO

Что мы тут имеем:

1. Корневой html-элемент #root, в который будет рендериться React-приложение
2. Подключение нужных библиотек по CDN (React и ReactDOM)
3. Подключение Babel для компиляции JSX-синтаксиса
4. Метод ReactDOM.render, который принимает JSX-разметку и элемент, в который ее нужно вывести

#началоработы #примерыкода #документация
Компоненты

React основан на компонентном подходе, компоненты - это кирпичики, из которых строится ваше приложение.

Создание компонентов - это, наверно, основное, чем мы будем заниматься в React.

Вообще есть два способа создать компонент - с помощью простой функции и с помощью класса. Пока разберем только первый, как самый популярный.

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

https://codepen.io/furrycat/pen/RwpjQKN

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

#примерыкода #началоработы #компоненты #документация
Важно: Всегда именуйте компоненты с заглавной буквы.

Если тег начинается со строчной буквы, React будет считать, что это обычный HTML-тег. А если с заглавной, то это уже компонент, который можно отрендерить.

#важно #началоработы #компоненты #документация
Передача параметров в компоненты

В компонент можно передать параметры - в React они называются пропсы (props). Это делается через атрибуты тега.

https://codepen.io/furrycat/pen/eYveVqX?editors=0010

Если нужно передать строку, то используйте кавычки, как мы всегда делаем с атрибутами. Для любого другого типа данных (через пропсы можно передать все, что угодно) потребуются фигурные скобки.

Функциональный компонент принимает объект props первым аргументом. Чтобы вывести полученные данные в разметке, используйте фигурные скобки. О JSX-разметке поговорим подробнее в следующий раз.

#началоработы #компоненты #примерыкода #документация
JSX

JSX - это нечто среднее между HTML и JS. Большей частью этот формат похож на HTML, но с некоторыми особенностями из JS.

По умолчанию в браузерах он не обрабатывается, поэтому нужен компилятор - Babel. Он преобразует JSX в обычный JavaScript и исполняет его.

По большому счету JSX в React не необходим, все то же самое можно написать прямо на JS (как получается после компиляции). Но этот формат кажется очень удобным, поэтому сразу начнем работать с ним.

Главные особенности работы с JSX:

👉 атрибуты указываются не в kebab-case, а в camelCase, как в JavaScript
👉 вместо class нужно писать className
👉 вместо for (для элементов label) нужно писать htmlFor
👉 обработчики событий на тегах тоже в camelCase

Фрагмент JSX - это обычное JS-выражение, которое можно поместить в переменную и делать с ним другие привычные операции, например, передавать в функции и возвращать из них (как мы делаем в компонентах).

Читать в документации (рус): https://ru.react.js.org/docs/introducing-jsx.html

#началоработы #jsx #документация
Выражения в JSX

Внутри JSX можно использовать различные JS-конструкции и выражения. Для этого предназначены фигурные скобки - все внутри них воспринимается именно как выражение и выполняется. В результате выполнения обычно получается фрагмент JSX или null, если ничего выводить не требуется.

https://codepen.io/furrycat/pen/yLMPKzW?editors=1010

Это можно использовать для условного рендеринга - когда в зависимости от некоторого условия выводится тот или иной фрагмент разметки или компонент (или вообще ничего не выводится).

#началоработы #jsx #документация
👍1
Вывод списков

Чтобы вывести несколько элементов внутри JSX, их нужно просто собрать в массив. Идеальный метод для этого Array.prototype.map. Он принимает любые данные в виде массива и может превратить их в фрагменты JSX. Полученный массив можно записать в переменную, а можно сразу вывести в JSX.

https://codepen.io/furrycat/pen/vYxpJea?editors=0010

Важно: каждый элемент списка должен иметь уникальный ключ (атрибут key).

#началоработы #jsx #примерыкода #документация
Классовые компоненты

С функциональными компонентами мы уже знакомы: https://yangx.top/react_junior/7

Кроме них есть еще классовые. Суть та же самая, но возможностей больше.

https://codepen.io/furrycat/pen/bGqaZdr?editors=0010

Класс должен быть унаследован от React.Component и иметь метод render(), который возвращает разметку компонента.

Название класса так же превращается в тег, который можно использовать в разметке.

И вы по-прежнему можете передавать в компонент пропсы (как атрибуты тега) - теперь они доступы в this.props.

#примерыкода #компоненты #началоработы #документация
Отрисовка компонентов

Логика рендера выглядит довольно очевидной, но лучше все же проговорить ее еще раз.

👉 Все начинается с метода ReactDOM.render(), который принимает корневую разметку (обычно в формате JSX) и элемент, в который нужно ее поместить.

👉 Если разметка представляет собой обычные html-теги, они и выводятся как обычные html-теги.

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

👉 Функциональный компонент просто вызывается как обычная функция, результатом этого становится новый фрагмент разметки, который вставляется на место кастомного тега.

👉 Если компонент классовый, то React вызывает его метод render(), который опять же возвращает фрагмент разметки.

👉 Все это происходит до того, пока не отрендерится все, что нужно.

#началоработы #компоненты #жизненныйциклкомпонента
Виртуальный DOM

С первого взгляда кажется, что при рендеринге React совершает стандартные операции с DOM-деревом: что-то вставляет, что-то удаляет и т.д.
Нет, в итоге это, конечно, так и есть, но сама техника немного сложнее.

React отдельно хранит "идеальное" представление интерфейса - виртуальное DOM-дерево. Если происходят какие-то изменения, то виртуальный DOM сравнивается с реальным и ищется самый короткий путь для обновления страницы.

С тонкостями виртуального DOM будем разбираться позднее, пока нужно просто знать, что он есть.

#началоработы #виртуальныйdom #документация
Состояние

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

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

Состояние есть только у классовых компонентах (с хуками будем разбираться позже). Так что если вам нужно что-то изменяющееся, выбирайте классы.

https://codepen.io/pen?editors=0010

Состояние должно храниться в свойстве класса this.state, а обновлять его нужно с помощью специального метода this.setState.

Обратите внимание:

👉 Компонент наследует от React.Component, в конструкторе вызывается super()
👉 Метод tick в обработчике клика нужно явно привязать к компоненту, чтобы не потерялся контекст выполнения
👉
Состояние обновляется только с помощью метода this.setState, простое присваивание останется незамеченным


#началоработы #примерыкода #состояние #ссылки
Передача функции в компонент

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

https://codepen.io/furrycat/pen/GRWOxZv?editors=0010

Например, эту функцию-коллбэк можно вызывать при клике на кнопку или изменении значения поля ввода.

#началоработы #компоненты #документация
Привязка контекста обработчиков

Обработчики событий у классовых компонентов удобно выносить в отдельные методы. Но нужно помнить о привязке контекста (this).

https://codepen.io/pen?editors=0010

Если внутри обработчика есть ссылки на компонент (обычно this.props или this.state/this.setState), то важно сохранять контекст, чтобы этот this при вызове ссылался именно на компонент.

Лучше всего это делать прямо в конструкторе.

#началоработы #примерыкода #компоненты #документация
Альтернатива биндингу обработчиков

При установке обработчиков событий в React-компонентах не забываем про сохранение контекста выполнения. Классический метод bind разобран выше. Но есть и альтернативы.

👉 Стрелочные функции

https://codepen.io/furrycat/pen/VwpXROe?editors=0010

Обработчик можно оформить как стрелочную функцию. Так как она будет создана внутри метода render, а следовательно при вызове в качестве this у нее будет сам компонент.

Большой минус этого подхода: функция будет создаваться заново при каждом рендере компонента.

👉 Синтаксис общедоступных полей классов

https://codepen.io/furrycat/pen/abJYMrg?editors=0010

Экспериментальная фича, которую нужно отдельно подключать в ваш проект: https://babeljs.io/docs/en/babel-plugin-proposal-class-properties.

Обработчик, объявленный таким образом, дополнительно привязывать к компоненту не нужно.

#началоработы #примерыкода #обработкасобытий #документация
Передача параметров в обработчик события

Иногда в обработчик требуется передать дополнительные параметры (кроме самого объекта события). Например, это может быть полезно внутри списков для указания конкретного элемента. И при этом нельзя забывать о сохранении контекста выполнения.

https://codepen.io/furrycat/pen/ExWEJWx?editors=0011

Для этого можно использовать стрелочные функции или привязывать аргументы с помощью метода bind.

#началоработы #примерыкода #обработкасобытий #документация
Асинхронный setState

Вот и первая ошибка новичка 🙂

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

https://codepen.io/furrycat/pen/VwpXNJr?editors=0010

Метод update() делает два вызова setState подряд, каждый из которых увеличивает value на 1. Но в результате мы получаем не 3, как предполагалось, а 2. Два вызова просто превратились в один.

#началоработы #ошибки #состояние #документация #примерыкода
Асинхронный setState. Решение

Если вы хотите использовать данные текущего состояния (или пропсов) в вызове setState, то следует воспользоваться его вариацией, которая принимает не объект, а функцию. В эту функцию передаются текущие (на момент выполнения!) state и props, а вернуть нужно объект с измененными полями.

https://codepen.io/furrycat/pen/eYvMaYJ?editors=0010

#началоработы #ошибки #состояние #примерыкода #документация
setState() - что нужно знать

👉 setState - единственный способ изменить состояние компонента. Простое присваивание в this.state работает исключительно в конструкторе.

👉 setState работает асинхронно. Для лучшей производительности несколько вызовов метода могут быть сгруппированы в одно обновление.

👉 В setState нужно передавать только те поля, которые изменились. Неизменные копировать необязательно. Изменения будут сложены со старым состоянием.

#началоработы #состояние #документация