# Создание React приложения
## Принципы построения страницы браузером
1. Построение объектных моделей
1. DOM
2. CSSOM
2. Построение модели визуализации (Render Tree)
3. Построение макета (Layout)
4. Отрисовка

Если изменился один из ранних шагов (например, JS добавил новых тегов на страницу), требуется выполнить все последующие шаги

## Объектные модели
В браузере внутренне представляются как частный случай графа - дерево.
- Корень дерева DOM - объект `document`
- Корень CSSOM - тег `body`


## DOM
Представляет иерархию всех узлов на странице

## CSSOM
Представляет иерархию селекторов

## Модель визуализации
Представляет результат обработки DOM и CSSOM.
В ней хранятся только те элементы, которые должны быть показаны.
Сюда не войдут:
1. Элементы с display:none
2. Элементы, которых нет в HTML, но стили имеются

## Virtual DOM
Концепция управления отрисовкой frontend-приложения.
- Все узлы DOM хранятся в специальном объекте
- Объект управляет необходимостью отрисовки всех узлов, а также их созданием
## Реализации vDOM
- snabbdom
- Maquette
- Blockdom
- virtual-dom by Matt Esch
- Mithril
- Bobril
- cito.js
[Список библиотек без virtual DOM](https://github.com/achou11/no-virtual-dom)
## Подключение React к web-странице
```html
<script src="https://unpkg.com/react@18/umd/react.production.min.js" crossorigin></script>
```
Подключает базовые инструменты библиотеки React
```html
<script src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js" crossorigin></script>
```
## Создание проекта
```javascript
const container = document.getElementById('app');
```
Ищет необходимый узел. В нём будет отрисовано React приложение
```javascript
const root = ReactDOM.createRoot(container);
```
Создаёт корневой узел в Virtual DOM для данного контейнера. Изменения узлов
у родительских элементов не учитываются
```javascript
root.render(App);
````
Отрисовывает начальную версию приложения
## Создание узлов
Вместо
```javascript
document.createElement(tagName);
````
Используется
```javascript
React.createElement(tagName, props, children1, children2, children3, ...);
````
- tagName - имя тега
- props - объект атрибутов тега. В React они называются props, сокращённо от properties.
- опционально. children - дочерние узлы элемента
## Установка Create React App через npx
1. Убедитесь, что у вас установлен NodeJS
2. Проверьте, что команда `node -v` выдаёт актуальную версию Node
```bash
npx create-react-app название_новой_папки_проекта
````
## Работа с JSX
React предлагает более удобный синтаксис для работы с DOM под названием JSX
- Файл не распознается браузером и требует преобразования в привычный JS
- Данной работой занимается Babel, который входит в состав CRA
Синтаксис похож на привычный HTML
## Передача значений
Осуществляется через атрибуты (props)
```javascript
<App data={results}/>
```
## Интерполяция
Для вставки в HTML подготовленных значений, используются фигурные скобки {}
```javascript
<div>{'Hello'}</div>
```
Выведет
```html
<div>Hello</div>
```
```javascript
<div>{['Oleg', 'Stepan', 'Inga'].map(v => <h2>{v}</h2>)}</div>
```
Выведет
```html
<div>
<h2>Oleg</h2>
<h3>Stepan</h3>
<h2>Inga</h2>
</div>
```
## Индексация списков
Для производительности и правильной отрисовки React должен знать о каждом элементе. Уникальность ему задают с помощью пропса key
```jsx
<div>{
['Oleg', 'Stepan', 'Inga'].map(
(value, index) => <h2 key={index}>{value}</h2>
)
}</div>
```
## Пример приложения
```javascript
function App({ data = [] }) {
return (
<div className='container'>
<h1 className='title'>Pokemon List</h1>
<div className='pokemon-list'>
{data.map(item =>
<div className='pokemon-list__item'>
<div className='pokemon-list__name'>
{item.name}
</div>
</div>
)
}
</div>
</div>
);
}
```
## Полезные части ES6 для React
1. [Spread-оператор (оператор распространения)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax)
2. [Rest-оператор (оператор взятия остатка)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters)
3. [Деструктуризация объектов](https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment)
4. Итерация массивов
1. [forEach](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach)
2. [map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map)
## Полезные материалы
[Страница проекта React](https://reactjs.org/)
[Страница проекта Create React App](https://create-react-app.dev/)
[Бесплатный курс от Udemy по оптимизации загрузки](https://www.udemy.com/course/optimizing-web-performance-and-critical-rendering-path/)
[Дерево. Теория графов](https://ru.wikipedia.org/wiki/%D0%94%D0%B5%D1%80%D0%B5%D0%B2%D0%BE_(%D1%82%D0%B5%D0%BE%D1%80%D0%B8%D1%8F_%D0%B3%D1%80%D0%B0%D1%84%D0%BE%D0%B2))
[Список материалов по оптимизации приложений](https://web.dev/learn/)
[Работа со списками](https://reactjs.org/docs/lists-and-keys.html)