Как подключить реакт к html
Перейти к содержимому

Как подключить реакт к html

  • автор:

Installation

React is flexible and can be used in a variety of projects. You can create new apps with it, but you can also gradually introduce it into an existing codebase without doing a rewrite.

Trying Out React #

If you're just interested in playing around with React, you can use CodePen. Try starting from this Hello World example code. You don't need to install anything; you can just modify the code and see if it works.

If you prefer to use your own text editor, you can also download this HTML file, edit it, and open it from the local filesystem in your browser. It does a slow runtime code transformation, so don't use it in production.

Creating a Single Page Application #

Create React App is the best way to starting building a new React single page application. It sets up your development environment so that you can use the latest JavaScript features, provides a nice developer experience, and optimizes your app for production.

Create React App doesn't handle backend logic or databases; it just creates a frontend build pipeline, so you can use it with any backend you want. It uses Webpack, Babel and ESLint under the hood, but configures them for you.

Adding React to an Existing Application #

Using npm #

We recommend using React from npm with a bundler like Browserify or webpack. If you use npm for client package management, you can install React with:

and import it from your code with something like:

This code renders into an HTML element with the id of root so you need <div > somewhere in your HTML file. When you use React in this way, you should be transpiling your JavaScript using Babel with the es2015 and react presets. To use React in production mode, set the environment variable NODE_ENV to "production" .

If you use Bower, React is available via the react package.

Enabling ES6 and JSX #

We recommend using React with Babel to let you use ES6 and JSX in your JavaScript code. ES6 is a set of modern JavaScript features that make development easier, and JSX is an extension to the JavaScript language that works nicely with React. The Babel setup instructions explain how to configure Babel in many different build environments. Make sure you install babel-preset-react and babel-preset-es2015 and enable them in your .babelrc , and you're good to go.

Using a CDN #

If you don't want to use npm to manage client packages, the react and react-dom npm packages also provide UMD distributions in dist folders, which are hosted on a CDN:

To load a specific version of react and react-dom , replace 15 with the version number.

Add React to a Website

React has been designed from the start for gradual adoption, and you can use as little or as much React as you need. Perhaps you only want to add some “sprinkles of interactivity” to an existing page. React components are a great way to do that.

The majority of websites aren’t, and don’t need to be, single-page apps. With a few lines of code and no build tooling, try React in a small part of your website. You can then either gradually expand its presence, or keep it contained to a few dynamic widgets.

Add React in One Minute

In this section, we will show how to add a React component to an existing HTML page. You can follow along with your own website, or create an empty HTML file to practice.

There will be no complicated tools or install requirements — to complete this section, you only need an internet connection, and a minute of your time.

Step 1: Add a DOM Container to the HTML

First, open the HTML page you want to edit. Add an empty <div> tag to mark the spot where you want to display something with React. For example:

We gave this <div> a unique id HTML attribute. This will allow us to find it from the JavaScript code later and display a React component inside of it.

Tip

You can place a “container” <div> like this anywhere inside the <body> tag. You may have as many independent DOM containers on one page as you need. They are usually empty — React will replace any existing content inside DOM containers.

Step 2: Add the Script Tags

Next, add three <script> tags to the HTML page right before the closing </body> tag:

The first two tags load React. The third one will load your component code.

Step 3: Create a React Component

Create a file called like_button.js next to your HTML page.

Open this starter code and paste it into the file you created.

Tip

This code defines a React component called LikeButton . Don’t worry if you don’t understand it yet — we’ll cover the building blocks of React later in our hands-on tutorial and main concepts guide. For now, let’s just get it showing on the screen!

After the starter code, add two lines to the bottom of like_button.js :

These two lines of code find the <div> we added to our HTML in the first step, and then display our “Like” button React component inside of it.

There is no step four. You have just added the first React component to your website.

Check out the next sections for more tips on integrating React.

Tip: Reuse a Component

Commonly, you might want to display React components in multiple places on the HTML page. Here is an example that displays the “Like” button three times and passes some data to it:

Note

This strategy is mostly useful while React-powered parts of the page are isolated from each other. Inside React code, it’s easier to use component composition instead.

Tip: Minify JavaScript for Production

Before deploying your website to production, be mindful that unminifed JavaScript can significantly slow down the page for your users.

If you already minify the application scripts, your site will be production-ready if you ensure that the deployed HTML loads the versions of React ending in production.min.js :

If you don’t have a minification step for your scripts, here’s one way to set it up.

Optional: Try React with JSX

In the examples above, we only relied on features that are natively supported by the browsers. This is why we used a JavaScript function call to tell React what to display:

However, React also offers an option to use JSX instead:

These two code snippets are equivalent. While JSX is completely optional, many people find it helpful for writing UI code — both with React and with other libraries.

You can play with JSX using

Quickly Try JSX

The quickest way to try JSX in your project is to add this <script> tag to your page:

Now you can use JSX in any <script> tag by adding type="text/babel" attribute to it. Here is an example HTML file with JSX that you can download and play with.

This approach is fine for learning and creating simple demos. However, it makes your website slow and isn’t suitable for production. When you’re ready to move forward, remove this new <script> tag and the type="text/babel" attributes you’ve added. Instead, in the next section you will set up a JSX preprocessor to convert all your <script> tags automatically.

Add JSX to a Project

Adding JSX to a project doesn’t require complicated tools like a bundler or a development server. Essentially, adding JSX is a lot like adding a CSS preprocessor. The only requirement is to have Node.js installed on your computer.

Go to your project folder in the terminal, and paste these two commands:

  1. Step 1: Run npm init -y (if it fails, here’s a fix)
  2. Step 2: Run npm install babel-cli@6 babel-preset-react-app@3

Tip

We’re using npm here only to install the JSX preprocessor; you won’t need it for anything else. Both React and the application code can stay as <script> tags with no changes.

Congratulations! You just added a production-ready JSX setup to your project.

Run JSX Preprocessor

Create a folder called src and run this terminal command:

Note

npx is not a typo — it’s a package runner tool that comes with npm 5.2+.

If you see an error message saying “You have mistakenly installed the babel package”, you might have missed the previous step. Perform it in the same folder, and then try again.

Don’t wait for it to finish — this command starts an automated watcher for JSX.

If you now create a file called src/like_button.js with this JSX starter code, the watcher will create a preprocessed like_button.js with the plain JavaScript code suitable for the browser. When you edit the source file with JSX, the transform will re-run automatically.

As a bonus, this also lets you use modern JavaScript syntax features like classes without worrying about breaking older browsers. The tool we just used is called Babel, and you can learn more about it from its documentation.

If you notice that you’re getting comfortable with build tools and want them to do more for you, the next section describes some of the most popular and approachable toolchains. If not — those script tags will do just fine!

Введение в React

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

1. Getting started with React

1.1 Методы добавления React

Существует 2 основных метода для добавления React на сайт:

  1. С помощью тэга <script />
  2. С помощью create-react-app

1.2 Выбор метода добавления

Выбор метода зависит от потребностей. Если вы просто хотите добавить немного интерактивности на существующую страницу или хотите просто попробовать React тогда используйте первый метод подключения. Если вы собираетесь построить полноценное React приложение, то используйте create-react-app.

1.2.1 Добавление React с помощью тэга <script />

Шаг 1 Добавьте 3 тега в контейнер head на вашей странице:

Здесь подключаются библиотеки React и React-dom, а также компилятор babel.

Шаг 2 Добавьте пустой контейнер на вашу страницу чтобы отметить место, где вы хотите что-либо отобразить с помощью React.
Шаг 3 Теперь вы можете использовать React вместе с JSX в любом теге script, добавив к нему атрибут type=«text/babel».

1.2.2 Добавление React с помощью create-react-app

Инструменты, используемые для разработки React, опираются на Node.js, поэтому первое что вам необходимо сделать, это установить Node, что бы использовать npm.

Пакет create-react-app является стандартным способом создания и управления сложными пакетами React и предоставляет разработчикам полный набор инструментов. Используйте create-react-app, для создания нового React приложения.

После установки nodejs, для установки create-react-app:

Выбор за вами какой инструмент использовать (npx, npm, yarn) для создания React приложения.

Когда вы создаете новое приложение, CLI будет использовать Yarn для установки зависимостей (если они доступны). Если у вас установлен Yarn, но вы предпочитаете использовать npm, вы можете добавить —use-npm к команде создания. Например:

Выполнение любой из этих команд создаст каталог с именем my-app внутри текущей папки. Внутри этого каталога будет сгенерирована исходная структура проекта и установлены необходимые зависимости:

Для запуска приложения в режиме разработки перейдите в папку с вашим приложением и выполните npm start или yarn start:

Страница автоматически перезагрузится, если вы внесете изменения в код. Вы увидите ошибки сборки и предупреждения в консоли. Откройте localhost:3000, чтобы просмотреть приложение в браузере.

Обратите внимание! Для сборки проекта эти файлы должны существовать с точными именами файлов:

  • public / index.html — шаблон страницы;
  • src / index.js — это точка входа JavaScript.

2. Basically React

2.1 React object

React — это точка входа в библиотеку React. При подключении React с помощью тега script, API верхнего уровня доступны в глобальном объекте React, а если вы используете ES6 и create-react-app, вы должны импортировать React объект:

Если же вы используете ES5 и create-react-app, вы можете импортировать React объект следующем образом:

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

2.2 React element

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

Для создания React элементов вам нужно использовать методы createElement() или
createFactory(). Последний считается устаревшим и его использование не рекомендуется поэтому не будем останавливаться на нём. Если вы используете JSX, то вам не придётся вызывать данные методы.

React предоставляет методы для клонирования — cloneElement, проверки — isValidElement() и работой с структурой данных props.children это React.Children (семейство методов React.Children).

Для отображения React элементов необходимо вызвать метод Render объекта ReactDom. После отображения (рендеринга) React элемента вы не можете изменить его потомков или атрибуты. Единственным решением является повторный вызов ReactDom.render(). На практике не советуется повторный вызов этого метода. Поэтому для интерактивных элементов вам необходимо использовать React компоненты.

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

В React элементах допустимо использование встраиваемых выражений Javascript.

Пример использования встраиваемого выражения:

Если вы не используете JSX, то вы можете использовать встраиваемые выражения передав их как один из аргументов методу createElement.

Пример использования встраиваемого выражения с методом createElement:

2.2.1 React.createElement

Для создания React элемента используйте метод createElement:

  • type — JavaSacript строка, содержащая имя тега, React-компонент или React-фрагмент;
  • props — props (свойство экземпляра React объекта)
  • children — Дочерний элемент для type.

Если же вы используете JSX, то у вас нет необходимости в специальных методах для создания React элемента.

Создание React элемента с использованием JSX:

Как вы могли заметить оба примера создают один и тот же объект. Таким образом из примера выше можно сделать вывод о том, что каждый элемент JSX это просто синтаксический сахар для вызова React.createElement().

Вы можете проверить это сами. Используя для этого онлайн компилятор Babel.

2.2.2 React.cloneElement

React.cloneElement — метод позволяющий клонировать React элементы.

Возвращает новый React элемент, используя переданный React элемент в качестве отправной точки. Аргументы такие же как у React.createElement() за исключением того, что первый параметр не имя нового тэга, а имеющиеся React элемент. Полученный элемент будет иметь пропсы исходного элемента, а новые пропсы будут поверхностно слиты воедино. Новые дочерние элементы заменят существующие. key и ref из исходного элемента будут сохранены.

2.2.3 React.isValidElement

React.isValidElement(object) — Проверяет, что объект является элементом React. Возвращает true в случае если объект является элементом React или false в случае если он не является элементом React.

2.2.4 React.Children

React.Children предоставляет функции для работы с непрозрачной структурой данных this.props.children. Если проще, то props.children это то, что вы включаете между открывающим и закрывающим тегами при вызове компонента.

Таким образом props.children может помочь сделать ваши компоненты React более гибкими и многократно используемыми. Вы можете использовать props.children для компонентов, которые представляют «общие блоки» и которые «не знают своих детей раньше времени». То есть в примере выше компонент Chill это шаблон, который можно использовать многократно с разным результатом. Конечно такой упрощенный пример сильно напоминает использование пропсов, но с помощью props.children вы можете строить более сложные структуры данных.

Давайте в вкратце рассмотрим методы для работы с props.children.

  • React.Children.map — создаёт новый массив с результатом вызова указанной функции для каждого элемента массива;
  • React.Children.forEach — выполняет указанную функцию один раз для каждого элемента в массиве;
  • React.Children.count — возвращает общее количество компонентов в children;
  • React.Children.only — если у children есть только один потомок (React элемент), то возвращает его иначе выдаёт ошибку;
  • React.Children.toArray — возвращает массива из children с ключами, заданные каждому дочернему элементу

Похож на Array.prototype.map(). Создаёт новый массив с результатом вызова указанной функции для каждого элемента массива. Вызывает функцию для каждого непосредственного потомка, содержащегося в children передавая их по очереди в thisArg. Если children — это массив, он будет пройден, и функция будет вызвана для каждого потомка в массиве. Если children равен null или undefined, этот метод вернёт null или undefined, а не массив. Если children — это React.Fragment, он будет рассматриваться как целый потомок, а элементы внутри не будут пройдены. Метод map вызывает переданную функцию callback один раз для каждого элемента, в порядке их появления и конструирует новый массив из результатов её вызова.

React.Children.forEach

Похож на Array.prototype.forEach(). Выполняет указанную функцию один раз для каждого элемента в массиве. В отличие от React.Children.map не возвращает массив из результатов вызова функции. Возвращает ubdefined.

Вы множите найти больше примеров тут и тут.

2.3 React компоненты

React компонент — функция возвращающая React-элемент или JavaScript класс реализующий метод render() который возвращает React-элемент. Соответственно компоненты, объявленные с помощью JavaScript функции принято называть «функциональными компонентами» а компоненты, объявленные с помощью JavaScript классов принято называть «классовыми компонентами».

Компоненты, объявленные как функции JavaScript не могут содержать «состояния», поэтому их также принято называть stateless components, то есть, компоненты без состояния, а компонентные объявленные как JavaScript класс могу содержать «состояние», поэтому их называют statefull components, то есть, компоненты с состоянием. *На самом деле вы можете добиться похожей функциональности и от функциональных компонентов используя хуки.

Классовые React-компоненты могут быть объявлены путём создания подклассов React.Component или React.PureComponent. Последний отличается лишь тем, что он реализует метод shouldComponentUpdate() (см. жизненный цикл компонентов).

Функциональный React-компонент это функция JavaScript, которая может быть обернута в React.memo. React.memo похож на React.PureComponent только предназначен для функциональных компонентов.

Пропсы — это просто аргументы передоверяемые компоненту. Когда React встречает JSX-атрибуты он собирает их в один объект и передаёт компоненту. Этот объект и называется «пропсы» (props).

Пример использования пропсов в функциональном компоненте:

React-компоненты обязаны вести себя как чистые функции по отношению к своим пропсам.

Компонент никогда не должен что-то записывать в свои пропсы — вне зависимости от того, функциональный он или классовый.

2.3.1 React.Component

React.Component — это базовый класс для компонентов React. Для создания React-компонента наследуйте свойства и методы от React.Component:

Каждый компонент имеет методы жизненного цикла, которые закономерно вызываются при монтировании, обновление и размонтировании компонента. Переопределение такого метода позволяет выполнять код на конкретном этапе этого процесса. (см. 2.3.5 Lifecycle).

2.3.2 React.Fragment

Как вы могли заметить любой React элемент и компонент должен возвращать только один узел (один html тэг). Если же вам необходимо отрендерить несколько тегов, то они в обязательном порядке должны быть обернуты в один контейнер иначе вы получите ошибку. Но что же делать, если не хочется создавать лишние контейнеры? Ответ: React.Fragment.

Компонент React.Fragment позволяет возвращать несколько элементов в методе render() без создания дополнительного элемента DOM:

Конечно, если вы не используете Jsx, то ваш код будет выглядеть так:

В React v16.2.0 завезли новый синтаксический сахар для React.Fragment, с этой версии вы можете просто писать пустой html тэг, который будет оборачиваться в React.Fragment:

2.3.3 State

Состояние компонента (State) — это приватное свойство (state) классовых React компонентов. Обновляя состояние с помощью метода setState() компонент рендерится повторно. Из этого следует запомнить что компонент не будет рендерится заново если изменять состояние напрямую (без вызова setState()).

Давайте рассмотрим простейшей пример с кнопкой счетчиком. В этом примере при нажатии на кнопку вызывается метод incrementCount который с помощью setState обновляет состояние компонента и компонент рендерится снова, отображая новое значение счетчика.

Давайте разберём код по частям.

Ключевое слово super() используется как функция, вызывающая родительский конструктор. Её необходимо вызвать до первого обращения к ключевому слову this в теле конструктора. Поэтому прежде чем инициализировать начальное состояние компонента необходимо вызвать super(). Классовые компоненты всегда должны вызывать базовый конструктор с аргументом props. Даже если вы не используете пропсы.

Для методов необходимо вызывать метод bind() который наследуется из Function.prototype.bind() он создаёт новую функцию, которая при вызове устанавливает в качестве контекста выполнения this предоставленное значение. Это нужно потому что методы класса в JavaScript по умолчанию не привязаны к контексту. Поэтому this будет undefined в момент вызова функции если не привязать ее к контексту. Есть способ позволяющий избежать вызова bind(), это использование синтаксиса общедоступных полей классов:

С помощью ключевого слова onClick регистрируется обработчик событий вызывающий метод incrementCount каждый раз, когда совершается событие. Особенности обработки событий на React будут рассмотрены в следующей главе.

setState() использует текущее значение состояния для его обновления. Поэтому вместо объекта с новым состоянием передаётся функция получающая текущее состояние как аргумент. Дело в том что вызовы setState являются асинхронными из за чего this.state в некоторых случаях может отображать неправильное значение. Для понимания этого давайте взглянем на синтаксис метода setState:

setState() напоминает функцию fetch() делающая запрос. Метод setState() не всегда обновляет компонент сразу. Он может группировать или откладывать обновление до следующего раза. Это делает чтение this.state сразу после вызова setState() потенциальной ловушкой. Первый аргумент функции updater имеет следующий вид:

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

Обновления состояния объединяются!

Если состояние хранит несколько значений, то изменение одно значения не повлияет на другое.

Оба поля можно обновить по отдельности с помощью отдельных вызовов setState()

Состояния объединяются поверхностно, поэтому вызов changeValue_1() оставляет value_2 нетронутым, но полностью заменяет value_1.

Состояние доступно только для самого компонента и скрыто от других. То есть this.state является приватным свойством.

Компонент может передать своё состояние вниз по дереву в виде пропсов дочерних компонентов.

2.3.4 Events

Обработка событии в React похожа на таковую в DOM-элементах за исключением синтаксических особенностей и некоторых особенностей реализации.

В React нельзя предотвратить события по умолчанию вернув false из обработчика события. Для этого нужно вызвать preventDefault().
Обработчики событий также получают объект Event, который в React называют SyntheticEvent. После вызова обработчика события объект SyntheticEvent повторно используется, а все его свойства будут очищены, поэтому нельзя использовать синтетические события асинхронно.

Но если же вы всё таки хотите использовать события асинхронно то вызывайте event.persist() на событии. Тогда оно будет извлечено из пула, что позволит вашему коду удерживать ссылки на это событие.

Список всех поддерживаемых событий вы можете посмотреть тут.

2.3.5 Lifecycle

Каждый компонент имеет несколько «методов жизненного цикла». Переопределение такого метода позволяет выполнять код на конкретном этапе этого процесса. Давайте рассмотрим все три этапа и разберёмся в какой последовательности, какие методы вызываются на различных этапах. И собственно, как вы можете использовать эти методы.

image

Монтирование

При монтирований (создание экземпляра компонента и его вставке в DOM) закономерно вызываются следующие методы в указанном порядке:

  • constructor()
  • static getDerivedStateFromProps()
  • render()
  • componentDidMount()

Конструктор — самый первый метод жизненного цикла, вызывается до того, как компонент будет примонтирован.

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

Как правильно определять состояние и привязывать методы к контексту в конструкторе я уже детально объяснил. (см. 2.3.3 State).

getDerivedStateFromProps()

getDerivedStateFromProps вызывается непосредственно перед вызовом метода render, как при начальном монтировании, так и при последующих обновлениях. Он должен вернуть объект для обновления состояния или null, чтобы ничего не обновлять. Этот метод существует для редких случаев, когда состояние зависит от изменений в пропсах. getDerivedStateFromProps существует только для одной цели. Он позволяет компоненту обновлять свое внутреннее состояние в результате изменений в props. Для лучшего понимания прочитайте статью Brian Vaughn, You Probably Don’t Need Derived State.

Так как это статический метод, он не имеет доступа к экземпляру компонента. Чтобы использовать пропсы, состояние и методы класса в getDerivedStateFromProps(), их нужно вынести за пределы класса в виде чистых функций.

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

Обратите внимание, что этот метод запускается при каждом рендере, независимо от причины.

При вызове он проверяет this.props и this.state и возвращает один из следующих вариантов:

  • Элемент React
  • Массив
  • Портал
  • Строку
  • Число
  • Booleans или null

Взаимодействовать с браузером необходимо в componentDidMount() или других методах жизненного цикла. Чистый render() делает компонент понятным.

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

componentDidMount()

componentDidMount() вызывается сразу после монтирования (то есть, вставки компонента в DOM). В этом методе должны происходить действия, которые требуют наличия DOM-узлов. Например, работа с анимацией или создание сетевых запросов.

Вы можете сразу вызвать setState() в componentDidMount(). Это вызовет дополнительный рендер перед тем, как браузер обновит экран. Гарантируется, что пользователь не увидит промежуточное состояние, даже если render() будет вызываться дважды. Правда при таком подходе возможны проблемы с производительностью. Начальное состояние лучше объявить в constructor(). Однако, это может быть необходимо для случаев, когда нужно измерить размер или положение DOM-узла, на основе которого происходит рендер. Например, для модальных окон или всплывающих подсказок.

Если монтирование происходит при создании экземпляра компонента и его рендеринге (передаче компонента в метод ReactDom.render()), то обновление происходит при последующих вызовах ReactDom.render(). Обновление происходит при изменении пропсов или состояния компонента. При повторном рендере компонента закономерно вызываются следующие методы в указанном порядке:

  • static getDerivedStateFromProps()
  • shouldComponentUpdate()
  • render()
  • getSnapshotBeforeUpdate()
  • componentDidUpdate()

forceUpdate()

Если ваш метод render() зависит от некоторых других данных, вы можете указать React необходимость в повторном рендере, вызвав forceUpdate().

Вызов forceUpdate() приведёт к выполнению метода render() в компоненте, пропуская shouldComponentUpdate(). Это вызовет обычные методы жизненного цикла для дочерних компонентов, включая shouldComponentUpdate() каждого дочернего компонента. React по-прежнему будет обновлять DOM только в случае изменения разметки.

В этом примере при нажатие на кнопку будет вызван handleClick который приведёт к обновлению компонента и вызову getSnapshotBeforeUpdate в Tittle который изменит значение свойства button.click перед тем как компонент будет отображён. В итоге при каждом нажатии кнопки надпись в Title будет сменятся.

Конечно это можно было реализовать проще, просто изменяя состояние Clicker в handleClick и передовая его как props в Tittle. Но этот пример хорошо демонстрирует работу forceUpdate(). Можно сказать, что forceUpdate() это замена для setState() когда необходимо принудительно обновить компонент. Вы можете использовать этот метод в двух случаях: когда вы не хотите реализовывать состояние компонента но хотите иметь способ принудительного обновления либо если вы хотите пропустить shouldComponentUpdate() при обновление компонента.

getDerivedStateFromProps()

Метод getDerivedStateFromProps() уже был рассмотрен выше так как он вызывается как при начальном монтировании, так и при обновлении компонента. Не ясно для чего он вызывается при монтировании. Поскольку его основной задачей по задумке разработчиков это возвращение объекта для обновления состояния или null, чтобы ничего не обновлять.

shouldComponentUpdate()

shouldComponentUpdate указывает на необходимость следующего рендера на основе изменений состояния и пропсов. По умолчанию происходит повторный рендер при любом изменении состояния. В большинстве случаев вы должны полагаться на это поведение. Но бывают специфические случае, когда, к примеру, необходимость в обновление компонента возникает только при изменение конкретного props или state, а во всех остальных случаях не требуется. Вы можете сравнить this.props с nextProps, а this.state с nextState, верните false чтобы пропустить обновление React.

Обратите внимание возврат false не предотвращает повторный рендер дочерних компонентов при изменении их состояния.

Значение по умолчанию равно true. Этот метод не вызывается при первом рендере или когда используется forceUpdate().

Поскольку лишние вызовы ReactDom.render() могут плохо сказаться на скорости работы вашего приложения, этот метод нужен только для повышения производительности. Не опирайтесь на возможность shouldComponentUpdate() «предотвратить» рендер, это может привести к багам.

Как говорилось ранее (см. 2.3 React компоненты) классовые React-компоненты которые объявляются путём создания подкласса React.PureComponent, а не React.Component по умолчанию реализуют метод shouldComponentUpdate().

Метод shouldComponentUpdate() базового класса React.PureComponent делает только поверхностное сравнение объектов. Если они содержат сложные структуры данных, это может привести к неправильной работе для более глубоких различий (то есть, различий, не выраженных на поверхности структуры). Наследуйте класс PureComponent только тогда, когда вы ожидаете использовать простые пропсы и состояние, или используйте forceUpdate(), когда знаете, что вложенные структуры данных изменились.

При обновление сразу после shouldComponentUpdate() вызывается render() принцип работы которого рассматривался выше.

getSnapshotBeforeUpdate()

getSnapshotBeforeUpdate() вызывается прямо перед этапом «фиксирования» (например, перед добавлением в DOM). Он позволяет вашему компоненту брать некоторую информацию из DOM (например, положение прокрутки) перед её возможным изменением. Любое значение, возвращаемое этим методом жизненного цикла, будет передано как параметр componentDidUpdate().

Хотя этот метод и вызывается после render() в нем вы все еще можете получить «снимок», то как выглядит DOM до рендера.

Значение снимка (или null) должно быть возвращено из этого метода.

componentDidUpdate()

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

В componentDidUpdate() можно вызывать setState(), однако его необходимо обернуть в условие, чтобы не возникла бесконечная рекурсия.

В тех редких случаях когда реализован метод жизненного цикла getSnapshotBeforeUpdate(), его результат передаётся componentDidUpdate() в качестве третьего параметра snapshot.

componentDidUpdate() не вызывается, если shouldComponentUpdate() возвращает false.

Размонтирование

При удалении компонента из DOM вызывается метод componentWillUnmount().

componentWillUnmount()

componentWillUnmount() вызывается непосредственно перед размонтированием (например при вызове ReactDOM.unmountComponentAtNode()) и удалением компонента. В этом методе выполняется необходимый сброс: отмена таймеров, сетевых запросов и подписок, созданных ранее.

2.3.6 Refs

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

Ситуации, в которых использования рефов является оправданным:

  • Управление фокусом, выделение текста или воспроизведение медиа.
  • Императивный вызов анимаций.
  • Интеграция со сторонними DOM-библиотеками.

Когда атрибут ref используется с классовым компонентом, свойство current объекта-рефа получает экземпляр смонтированного компонента.

Нельзя использовать ref атрибут с функциональными компонентами, потому что для них не создаётся экземпляров. Для этого используйте хук useRef . Говоря проще реф это ссылка на DOM элемент либо на экземпляр смонтированного компонента.

В этом примере this.ref это ссылка на дом элемент h1 — Hello world. При нажатии на кнопку вызывается функция handleClick использующая ссылку на h1 через ref и рандомно изменяет цвет текста.

Узнайте больше о Рефах здесь.

2.4 ReactDOM

Если объект React из react предоставляет API для создания и произведения различных манипуляции над React объектами и компонентами, то ReactDom предоставляет API для рендеринга этих компонентов или объектов.

Под рендерингом понимается отображение элементов или компонентов на странице.

Методы, предоставляемые пакетом ReactDom:

  • render() — Рендерит React-элемент в DOM-элемент;
  • hydrate() — Рендерит React-элемент в DOM-элемент используя HTML-содержимое которого было отрендерено с помощью ReactDOMServer;
  • unmountComponentAtNode() — Удаляет смонтированный компонент React из DOM и очищает его обработчики событий и состояние;
  • createPortal() — Создаёт портал.
2.4.1 Render

Рендерит React-элемент в DOM-элемент, переданный в аргумент container и возвращает ссылку на корневой экземпляр ReactComponent или null для компонентов без состояния.

Любые существующие дочерние элементы DOM container заменяются при первом вызове.
Другими словами — если вы рендерите в DOM узел, заведомо имеющий какие-либо дочерние элементы, то они будут удалены и заменены на element.

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

Если дополнительно был предоставлен колбэк, он будет вызван после того, как компонент отрендерится или обновится.

2.4.2 Hydrate

Тоже самое что и ReactDOM.render но для случаев, когда рендеринг на клиенте основан на результатах серверного рендеринга. Что такое Server-Side Rendering я объяснять не собираюсь. Для этого уже написана отдельная статья и соответсвующий раздел документации ReactDOMServer.

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

Если атрибут отдельного элемента или текстовое содержимое неизбежно отличается на сервере и клиенте (например, отметка времени), вы можете отключить предупреждение, добавив к элементу suppressHydrationWarning=. Он работает только на один уровень в глубину, и задумана как лазейка. Не злоупотребляйте ею.

2.4.3 UnmountComponentAtNode

Удаляет смонтированный компонент из container и очищает его обработчики событий и состояние. Если в контейнер не было смонтировано ни одного компонента, вызов этой функции ничего не делает. Возвращает true, если компонент был размонтирован, и false если нет компонента для размонтирования. Не перепутайте, container это не React элемент который необходимо удалить, а DOM узел в котором находится компонент.

2.4.4 CreatePortal

Порталы позволяют рендерить дочерние элементы в DOM-узел, который находится вне DOM-иерархии родительского компонента.

child — это любой React-компонент, который может быть отрендерен
container — это ссылка на DOM-элемент.

Что бы понять принцип действия порталов давайте рассмотрим простой пример:

Теперь используя портал, можно изменить то куда будет отрендерин компонент, точнее часть компонента:

image

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

3. Other topics

Здесь будут рассмотрены прочие темы, которые на мой взгляд не относятся к базовым понятиям React. В общем то прочитав первые два пункта 1. Getting started with React и 2. Basically React вы уже будете обладать достаточными знаниями для начала работы с React.

3.1 Lists and Keys

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

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

Давайте рассмотрим простой пример: у нас есть список друзей пользователя, который мы хотим отобразить в сайдбар. Мы можем сделать это следующим образом:

В главе 2.3.5 Lifecycle при рассмотрение метода render() вы узнали, что данный метод может возвращать не только React элементы или компоненты, но также и массивы, фрагменты, порталы, строки, числа, Booleans или null. Таким образом вы можете вернуть массив пользователей, состоящий из элементов React. Это конечно удобно, но при возвращении массива из компонента, вы получите следующее предупреждение:
Warning: Each child in a list should have a unique «key» prop.

У каждого ребенка в списке должно быть уникальное свойство «key».

Key это специальный строковый атрибут, который нужно указывать при создании списка элементов. Он нужен для оптимизации работы React при изменении DOM с течением времени. Для большего понимания работы React при изменение DOM прочитайте статью Алгоритм сравнения. Ключи должны быть уникальны в пределах одного списка элементов. Если переписать компонент с использованием Key то он будет выглядеть следующим образом:

На самом деле использование индекса элемента для атрибута Key, как в примере выше является плохой практикой в случаях, когда порядок элементов может поменяться потому что это может негативно сказаться на производительности и вызвать проблемы с состоянием компонента. Поэтому лучше использовать ID из ваших данных. Ключи не будут отображаться как атрибуты в DOM элементах, они являются свойствами React элементов. Вы можете убедится в этом вызвав обьект элемента в консоле с помощью element.__reactInternalInstance$235y8cxv0e8 (возможно после $ у вас будет другое число). element.__reactInternalInstance$235y8cxv0e8 — эксперементальное свойство, не опирайтесь на него при разработке.

3.2 Error Handling

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

Ошибка JavaScript где-то в коде UI не должна прерывать работу всего приложения. Для этого были добавлены специальные методы отлавливающие ошибки JavaScript в любом месте деревьев их дочерних компонентов, для сохранения их в журнале ошибок и вывода запасного UI вместо рухнувшего дерева компонентов. Они отлавливают ошибки при рендеринге, в методах жизненного цикла и конструкторах деревьев компонентов, расположенных под ними. Объекты реализующие такие методы принято называть «Предохранители». Вы можете узнать больше о предохранителях в специальном разделе документации Error Boundaries. Работают они следующем образом: если возникают ошибки в дочерних элементах предохранителей, они вызывают специальные методы и рендерят запасной вариант вместо рухнувшего интерфейса.

JavaScript язык с динамической типизации. Такой вариант типизации сильно облегчает работу для программистов, но может привести к сложным ошибкам. Инструменты для статической типизации, такие как Flow или TypeScript, позволяют отлавливать большую часть таких ошибок ещё до исполнения кода. Кроме того, они существенно улучшают процессы разработки, добавляя авто дополнение и другие возможности. Для использования статической типизации при написании React приложений прочитайте соответствующий раздел документации Static Type Checking.

Но даже если вы не используете расширения вроде Flow и TypeScript React предоставляет встроенные возможности для проверки типов. Это проверка типов с помощью PropTypes. Для проверки на правильность переданных типов данных в пропсы компонента вам нужно использовать специальное свойство propTypes:

При этом если вместо строки передать число (как показано выше), то в консоле можно будет увидеть следующее предупреждение: Warning: Failed prop type: Invalid prop `name` of type `number` supplied to `PropTypesExample`, expected `string`.

Также для обнаружения потанцеальных проблем вам может помочь Строгий режим (StrictMode). Также, как и Fragment, StrictMode не рендерит видимого UI. Строгий режим активирует дополнительные проверки и предупреждения для своих потомков.

Используйте библиотеку React Testing Library для написания тестов. В качестве альтернативы используйте утилиту тестирования Enzyme, которая легко позволяет делать проверки, управлять, а также просматривать выходные данные React-компонентов. Также прочитайте специальный раздел документации React (Testing) что бы знать больше о тестах.

3.2.1 getDerivedStateFromError

Этот метод жизненного цикла вызывается после возникновения ошибки у компонента-потомка. Он получает ошибку в качестве параметра и возвращает значение для обновления состояния.
Стоит отметить места, в которых данные методы не отловят ошибки: в обработчиках событий, асинхронном коде, серверном рендеринге, самом предохранителе. Поэтому если ошибка произойдет в дочернем компоненте, то она будет отловлена и вызваны методы static getDerivedStateFromError() и componentDidCatch().

Начиная с React 16, ошибки, не отловленные ни одним из предохранителей, будут приводить к размонтированию всего дерева компонентов React.

3.2.2 componentDidCatch

Этот метод также, как и getDerivedStateFromError отвечает за обработку ошибок и вызывается сразу после getDerivedStateFromError. Если предназначение getDerivedStateFromError это вернуть значение для обновления состояния, то предназначение componentDidCatch это логирование ошибок. То есть в componentDidCatch вы должны писать код для журналирования информации об отловленной ошибке.

Этот метод получает два параметра:
error — перехваченная ошибка
info — объект с ключом componentStack, содержащий информацию о компоненте, в котором произошла ошибка.

Дополняя предыдущий пример методом componentDidCatch получаем следующий код:

Методы console были добавлены только для того то бы показать из чего состоят объекты ошибки. В консоле получаем следующее:

image

Заключение

Спасибо что прочитали мою статью «Введение в React». Эта статья затрагивает основные (и не только) темы и концепции React. После прочтения данной статьи вы будете обладать хорошим фундаментом теоретических знаний о React которых будет достаточно для грамотного начала вашего первого проекта. Я надеюсь, что эта статья поможет вам в освоении React’а. Конечно для разработки настоящих проектов знаний одного только React вам будет явно недостаточно. Вы скорее всего будете использовать кучу других библиотек и пакетов для написания более сложных интерфейсов. Да и для того что бы облегчить себе работу (зачем изобретать велосипед) если кто-то уже его изобрёл. Скорее всего вы будете использовать Redux для лучшей работы с хранилищем, React Router для обеспечения URL-маршрутизации, Axios для выполнения асинхронных HTTP-запросов, GraphQL JS удобный язык запросов для API, а также огромное количество других API. Пишите в комментариях какие библиотеки используете вы.

Добавляем React на сайт

These docs are old and won’t be updated. Go to react.dev for the new React docs.

See Add React to an Existing Project for the recommended ways to add React.

Используйте React в том объёме, в котором вам хочется.

Для внедрения React не надо ничего переписывать. Его можно использовать как для маленькой кнопки, так и для целого приложения. Возможно, вы захотите немного «оживить» вашу страницу. React-компоненты подходят для этого как нельзя лучше.

Большинство сайтов в Интернете является обычными HTML-страницами. Даже если ваш сайт не относится к одностраничным приложениям, вы можете добавить на него React, написав всего несколько строк кода без каких-либо инструментов сборки. В зависимости от целей, можно постепенно перенести на React весь сайт или переписать всего несколько виджетов.

Добавляем React за одну минуту

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

Мы не будем пользоваться сложными инструментами сборки или что-то устанавливать. Всё, что вам нужно — это доступ к Интернету и минута свободного времени.

Шаг 1: Добавляем DOM-контейнер в HTML

Для начала, откройте HTML-файл страницы, которую хотите отредактировать. Добавьте пустой тег <div> в месте, где вы хотите отобразить что-нибудь с помощью React. Например:

Затем назначьте созданному <div> уникальный атрибут id . Это позволит впоследствии найти тег из JavaScript-кода и отобразить React-компоненты внутри него.

Совет

«Контейнер» <div> можно поместить где угодно внутри тега <body> . Вы можете создать любое количество независимых DOM-контейнеров на одной странице. Эти контейнеры принято оставлять пустыми, так как React в любом случае заменяет всё их содержимое.

Шаг 2: Добавляем script-теги

Теперь добавьте три <script> -тега перед закрывающим тегом </body> :

Первые два тега загружают React. Третий тег загружает код вашего собственного компонента.

Шаг 3: Создаём React-компонент

Создайте файл с именем like_button.js рядом с вашим HTML-файлом.

Возьмите этот стартовый код и вставьте его в созданный ранее файл.

Совет

В данном коде создаётся React-компонент с именем LikeButton . Не беспокойтесь, если что-то кажется вам непонятным — мы подробно разберём принципы разработки на React позже, в нашем практическом руководстве и во введении в основные понятия. Пока же мы просто посмотрим, как это выглядит на экране.

Добавьте ещё 3 строки в конец файла like_button.js , после стартового кода:

Эти три строки кода ищут элемент <div> , который мы добавили в HTML на первом шаге, а затем отображают React-компонент с кнопкой «Нравится» внутри него.

Вот и всё! Вы только что добавили свой первый React-компонент на страницу.

Перейдите к следующим разделам, если хотите узнать о других способах добавить React.

Совет: Повторное использование компонентов

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

Примечание

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

Совет: Минификация JavaScript для продакшена

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

Если вы уже минифицируете свои скрипты, то не забудьте подготовить к продакшену сам React. Для этого поменяйте окончания ссылок на React на production.min.js :

Если же вы не настроили минификацию для ваших скриптов, то вот один из вариантов, как это сделать.

Необязательно: Используем React с JSX

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

Однако, React позволяет использовать специальный синтаксис, называющийся JSX:

Эти два примера делают одно и то же. Несмотря на то, что JSX является совершенно необязательным, многие разработчики считают его удобным для разработки UI — как с React, так и с другими библиотеками.

Вы можете попробовать JSX в этом онлайн-конвертере.

Быстрый старт с JSX

Чтобы быстро попробовать JSX, добавьте такой <script> -тег на страницу:

Теперь синтаксис JSX доступен внутри каждого <script> -тега, у которого есть атрибут type=»text/babel» . Скачайте пример HTML-кода с JSX, чтобы поэкспериментировать.

Такой подход удобен для обучения или создания быстрых демо, но следует помнить, что работа сайта при этом сильно замедляется. Поэтому для продакшена JSX лучше добавить по-другому. Если вам интересно попробовать, удалите добавленный ранее <script> -тег и все атрибуты type=»text/babel» . Вместо них мы будем пользоваться препроцессором JSX, который автоматически трансформирует весь код внутри <script> -тегов.

Добавляем JSX в проект

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

С помощью терминала перейдите в директорию вашего проекта и запустите следующие команды:

  1. Шаг 1: Запустите команду npm init -y (если появляются ошибки, попробуйте этот способ)
  2. Шаг 2: Запустите команду npm install babel-cli@6 babel-preset-react-app@3

Совет

Мы используем npm только для установки препроцессора JSX. React и код приложения всё ещё остаются в <script> -тегах.

Поздравляем! Вы только что добавили в ваш проект поддержку JSX, готовую к продакшену.

Запускаем препроцессор JSX

Создайте директорию с названием src и наберите в терминале следующую команду:

Примечание

npx не является опечаткой. Это инструмент запуска пакетов, появившийся в npm версии 5.2+.

Если у вас появляется сообщение об ошибке, похожее на «You have mistakenly installed the babel package», то это означает, что вам нужно пройти предыдущий шаг, а затем повторить запуск команды.

Дожидаться завершения работы команды не нужно — она работает в режиме наблюдения за изменениями в JSX-коде.

Попробуйте создать файл с названием src/like_button.js и вставить в него этот стартовый JSX-код. Препроцессор автоматически трансформирует новый код в чистый JavaScript, пригодный для выполнения в браузере, и сохранит его в новый файл like_button.js . При редактировании JSX-кода в существующих файлах трансформация также происходит автоматически.

Кроме препроцессинга JSX, вы в качестве бонуса получаете синтаксические новинки JavaScript, такие как классы, без головной боли с их браузерной поддержкой. Всё это доступно благодаря использованию инструмента под названием Babel, информацию о котором вы можете узнать из его документации.

Если вы неплохо разбираетесь в инструментах сборки и хотите создавать приложения на React с их помощью, обратитесь к следующему разделу, где описаны некоторые из наиболее популярных способов. Если нет — не беспокойтесь, уже знакомые нам script-теги ничуть не хуже!

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *