Фронтенд разработка на ReactJs./ Старт проекта. Рендеринг html элементов.

Теги: js react start

Cтарт проекта. Рендеринг html элементов.

Реакт - это библиотека для построения пользовательского интерфейса.

Причем работает он со множеством платформ, включая мобильные.

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

В основу Ректа положена компонентная структура.

Компонент рассматривается как основной строительный блок для приложения.

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

Программист создает компоненты, их наполняет логикой и структурирует, влаживая один в другой.

При этом реакт предоставляет декларативный подход, когда при программировании мы описываем то, ЧТО должно быть выполнено а не то КАК это должно быть выполнено, как это происходит при декларативном программировании.

Затем Реакт публикует их на странице (рендерит) и следит за их перерисовкой в случае изменения данных.

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

Компонент может быть постоен на классах равно как и на функциях.

На классах.

class MyReactClassComponent extends Component {
    render() {}
}

На функциях.

function App() {
  return ();
}

export default App;

Программист решает какого размера будет компонент, какие html теги он будет содержать и как себя вести.

Для того, чтобы наполнять компоненты данными существуют 2 сущности:

  • свойства (props) - это то, что не меняется (например цвет фона)

  • состояния (states) то, что меняется (например вводимый пользователем текст)

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

react

Изнутри реакт имеет основную (ядро) библиотеку react и библиотеки для рендеринга (генерации) компонентов под разные устройства:

  • react-DOM - для браузеров

  • react-native - для мобилок

  • react-vr - для устройств виртуальной реальности

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

react

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

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

В этой ситуации очень важна эффективность и скорость работы.

Проблема в том, что если перерисовывать элементы при помощи нативных средств браузера (обычным DOM-ом) - это будет очень медленно работать при большом количестве элементов и операций.

Как выглядит DOM (модель документа)

react

Поэтому реакт внутри cебя создает свой слой абстракции, называемым виртуальным DOM. Это своего рода зеркало обычного DOM но с повышенной эффективностью. В нем скрыты все механизмы обнаружения изменений и отображение изменений в реальный DOM.

react

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

Как реакт определяет изменилось ли чего?

react

В оперативной памяти он создает виртуальный DOM и следит за тем, чтобы он совпадал с реальным DOM. Как только обнаруживает что это не так (функция Diff), он перерисовывает реальный DOM (функция Patch)

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

Установка.

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

npx create-react-app my-app --template typescript

Существует альтернативный установщик yarn.

yarn create react-app —template typescript

Он решает следующие проблемы npm (npx)

  • установка пакетов не достаточно быстрая и последовательная;

  • проблемы с безопасностью, так как npm позволяет пакетам запускать код при установке.

react

Затем запустить сервер

cd my-app
npm start

react

И наблюдать стартовую страницу по адресу http://localhost:3000/.

react

Берем типовое приложение постов пользователей (типа форума).

react

Как видим, эта задача может быть решена разбиением страницы поста на 3 компонента.

При этом один из компонентов (комментарии) будет использован в цикле.

Основная мощь любого компонента в том, что он существует независимо, сам по себе и может быть внедрен куда угодно. Это называют словами как stateless encapsulated reuseble composable.

Подобно конструктору LEGO все его части одинаковой формы и взаимозаменяемы.

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

Обычно для этого существует REST API сервер, на который отсылается HTTP запрос и он возвращает данные в формате json.

react

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

Причем одни компоненты могут содержать другие и быть родительскими по отношению к ним.

А могут быть Standalone (сами по себе).

Т.е. одни компоненты более “умные” (statefull) и ими мы забираем данные, а другие “глупые” (stateless), которые эти данные принимают и отображают.

Причем если нам нужно отреагировать на событие “глупого” компонента внутри “умного” (например чтобы отправить пост на сервер) мы должны будем “протащить” это событие в виде свойств (props) из глупого в умный.

Создание компонентов.

react

Первым делом мы создаем целевой html блок и забираем его в переменную.

Создание элемента React.

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

Такая функция есть!

React.createElement(
    String/ReactClass type,
    [object props],
    [children...]
) -> React Element
  • type - h1, div, span и т.д.

  • props - css class, id и т.д.

  • children - для внедрения дочерних элеметов (а вот тут и сила брат!)

Также должна быть функция для рендеринга этих элементов в целевой блок (контейнер).

И такая функция есть!

ReactDOM.render( 
    ReactElement element, DOMElement container, [function callback]
) -> ReactComponent

Как результат имеем:

react

Естественно, что в дальнейшем, реакт-элементы будут отображены на реальный DOM через react-dom или в мобилку через react-native.

react

Полный процесс.

react

Ну и еще подробней для совсем непонятливых.

react

Конечно, очень неудобно постоянно использовать createElement, и поэтому изобрели такой стандарт как JSX.

Он коллосально упрощает задачу.

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.tsx</code> and save to reload.
        </p>
      </header>
    </div>
  );
}

При этом расширение файлов для typescript меняется с ts на tsx!

И в настроечный файл tsconfig.js добавляется соответствующий флаг.

При написании такого подобия html нужно помнить что не все аттрибуты так же названы как и в html.

Например вместо class необходимо писать className по той простой причине что этот псевдоHTML скармливается javascript-у, а у него class - это ключевое слово.

{
  "compilerOptions": {
    ...
    "jsx": "react"
  }...

Контроль переменных.

Для того, чтобы описывать и контролировать данные, передаваемые компоненту, используют библиотеку prop-types.

....

import PropTypes from "prop-types";

Post.propTypes = {
    user: PropTypes.string.isRequired,
    content: PropTypes.string.isRequired,
    id: PropTypes.number.isRequired
};

const App = React.createElement(Post, {
    id: 1,
    content: ' said: This is a post!',
    user: 'mark'
});

render(App, node);

Приватная часть проекта.

Так я назвал папку scr в которой содержится код проекта.

Взглянем на файл index.tsx.

Это точка входа в приложение и с него начинается его выполнение.

react

Как видим в 4 строке импортируется компонент (функциональный) и далее он скармливается функции render как будто это тег .

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);

Что еще раз говорит о том, что jsx это не чистый HTML а псевдо-язык, похожий на XML, который передается js-у для дальнейшего разбора и перевода в такой вид:

React.createElement(...,..., 
    React.createElement(...,..., 
        React.createElement(...,...,и т.д.)))

В дальнейшем мы будем использовать исключительно jsx и за его удобства.

Компонент App

import React from 'react';
import logo from './logo.svg';
import './App.css';

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.tsx</code> and save to reload.
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
      </header>
    </div>
  );
}

export default App;

Туту стоит отметить

export default App;

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

import App from './App';

При НЕ дефолтном экспорте.

export function App() {...}

Импорт будет чуть длиннее.

import { App } from './App';

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

Все компоненты принято называть с заглавной буквы.

Группировка компонентов.

Когда в одном компоненте мы групируем несколько, то мы не можем возвратить больше одного элемента так:

export default function App() {
    return (
        <CurrentDate />
        <CurrentTime />
    );
}

Для этого нужно использовать специальные механизмы группировки нескользо компонентов (или html тегов) в один.

export default function App() {
    return (
        <React.Fragment>
        <CurrentDate />
        <CurrentTime />
        </React.Fragment>
    );
}

Или так

export default function App() {
    return (
    <>
        <CurrentDate />
        <CurrentTime />
    
    );
}

Публичная часть.

В проекте есть папка public. В нее складываются файлы, которые загружаются браузером первым делом.

К ним относятся index.html и все статичные файлы, стили, картинки и т.д.

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

import "./styles.css";

Можно использовать аттрибут style.

function Intro() {
    return <p style={{ color: "green" }}>
    Some intro text</p>;
}

Вторые скобки указывают на создание объекта.

При этом мы свободны в использовании языка и всяких вычислений.

<p
style={{
    fontSize: "125%",
    color: Math.random() < 0.5 ? "red" : "green"
}}>
Toto, I’ve got a feeling we’re not
in Kansas anymore
</p>

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

Как видим стартовый файл index.html довольно прост.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="theme-color" content="#000000" />
    <meta
      name="description"
      content="Web site created using create-react-app"
    />
    <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
    <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
    <title>React App</title>
  </head>
  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
  </body>
</html>

Плюс он не содержит никаких скриптов приложения.

Тогда как же приложение работает.

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

Он и делает всю черновую работу, компилирует скрипты, выводит их на страницу, запускает веб-сервер и следит за изменениями кода.

При любых изменениях он пересобирает проект и обновляет страницу браузера.

Очень удобно, но также и очень загадочно.

Webpack имеет свой настроечный файл для управления его работой, но по непонятным мне причинам его не включили в сборку проекта.

Список постов.

Создать 3 компонента для вывода поста и списка комментариев.

  1. Компонент - сборочный, который собирает внутри 2 другий.

  2. Компонент поста.

  3. Компонент комментария.

При этом комментарии вывести циклом (5 штук).

Все данные зашить внутри HTML статично.

Привести внешний вид к соответствию макета.

start page

Задать вопрос, прокомментировать.