Блог экспериментатора инженера-разработчика: Infanty.
Я пишу how-to статьи на редкие темы или статьи обзоры - для себя и тех кто со мной работает.
Блог существует при поддержке: "Оккупационных сил Марса".

React.js можно считать наилучшей альтернативой среди средств для разработки веб-интерфейсов. Разработка на React.js заключается в описании того, что нужно вывести на страницу (это называется: декларативный подход к описанию интерфейсов). Т.е. Вам всё равно - как браузер, на программном уровне, будет выводить элементы интерфейса на страницу.

При старте разработки проекта на React.js - Вам необходимо нарисовать прямоугольники вокруг каждого элемента (и под-элемента) в макете и дать им всем имена, после чего реализовать каждый элемент в отдельном компоненте React.js приложения.

Компонент может быть контейнером для нескольких под-компонентов (как на изображении выше). Но важно помнить три правила:

  • Все что возвращает компонент должно быть обернуто в один div.
  • Компонент должен решать только одну задачу и должен делать это качественно (принцип единственной ответственности - Single Responsibility Principle (SRP)).
  • Помещайте каждый компонент в отдельный файл (рекомендация для больших проектов).

Рассмотри React.js на 5-ти примерах (без использования Create React App и других инструментов) - для того, чтобы понять его основы и научится верстать макеты сайтов на React.js на основе функциональных компонентов не имеющих состояний.

Пример 1: "Hello World"

Простой пример показывающий как начать использовать React.js.

Содержимое index.html:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Hello World</title>
    
    <!-- Для работы React -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.development.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.development.js"></script>
    
    <!-- Для работы JSX -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.26.0/babel.js"></script>
  </head>
  <body>
    <div id="root"></div>
	
    <!-- Вывод заданного HTML в DIV с заданным Id -->
    <script type="text/babel">
      ReactDOM.render(
        <h1>Hello, world!</h1>,
        document.getElementById('root')
      );
    </script>
  </body>
</html> 

Пример 2: вынос React приложения из HTML в отдельный файл

Модифицируем пример 1, разделив HTML и React.js приложение.

Содержимое index.html:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Hello World</title>
    
    <!-- Для работы React -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.development.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.development.js"></script>
    
    <!-- Для работы JSX -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.26.0/babel.js"></script>
  </head>
  <body>
    <div id="root"></div>

    <!-- React приложение -->
    <script type="text/babel" src="./app.jsx"></script>
  </body>
</html> 

Содержимое app.jsx:

ReactDOM.render(
  <h1>Hello, world!</h1>,
  document.getElementById('root')
); 

Пример 3: реализация простого макета сайта на React.js

Модифицируем пример 2, изменив содержимое app.jsx, так - чтобы получилась реализация макета как на изображении в начале статьи. При этом содержимое файла: index.html - останется без изменений.

Важно, что из всех надписей на изображении в начале статьи - только заголовок статьи: Header Title не будет реализован как компонент. Так как в компоненте Header содержится только один логический блок - вывод заголовка: Header Title. Если в компоненте Header - выводилась бы ещё и информация о пользователе, то имело бы смысл заголовок статьи поместить в свой компонент, а информацию о пользователе в свой. Или же, если бы, заголовок статьи выводился минимум дважды в компоненте Header, то имело бы смысл заголовок статьи поместить в свой компонент.

// Компонент List Item.
class ListItem extends React.Component {
  render() {
    return <div className="list-item">List Item</div>;
  }
}

// Компонент List.
class List extends React.Component {
  render() {
    return <div className="list">
      <ListItem />
      <ListItem />
      <ListItem />
      <ListItem />
    </div>;
  }
}

// Компонент Header.
class Header extends React.Component {
  render() {
    return <div className="header">Header Title</div>;
  }
}
 
// Компонент Wrapper, содержащий "вызовы" компонентов Header и List.
class Wrapper extends React.Component {
  render() {
    return <div className="wrapper">
      <Header />
      <List />
    </div>;
  }
}
 
// Отображение компонента - Wrapper, описанного выше, на узле DOM с Id: root.
ReactDOM.render(
  <Wrapper />,
  document.getElementById('root')
); 

Пример 4: рефакторинг макета сайта на React.js - разделение компонентов

Поместим каждый компонент в отдельный файл. Тогда содержимое index.html изменится, на:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Hello World</title>
    
    <!-- Для работы React -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.development.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.development.js"></script>
    
    <!-- Для работы JSX -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.26.0/babel.js"></script>
  </head>
  <body>
    <div id="root"></div>

    <!-- Компонент List Item -->
    <script type="text/babel" src="./list-item.jsx">
      import ListItem;
    </script>
    <!-- Компонент List -->
    <script type="text/babel" src="./list.jsx">
      import List;
    </script>
    <!-- Компонент Header -->
    <script type="text/babel" src="./header.jsx">
      import Header;
    </script>
    <!-- Компонент Wrapper -->
    <script type="text/babel" src="./wrapper.jsx">
      import Wrapper;
    </script>
    <!-- React приложение -->
    <script type="text/babel" src="./app.jsx"></script>
  </body>
</html> 

A содержимое app.jsx изменится, на:

// Отображение компонента - Wrapper, описанного в wrapper.jsx, на узле DOM с Id: root.
ReactDOM.render(
  <Wrapper />,
  document.getElementById('root')
); 

Пример 5: рефакторинг макета сайта на React.js - оптимизация компонентов

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

// Компонент Wrapper, содержащий "вызовы" компонентов Header и List.
class Wrapper extends React.Component {
  render() {
    return <div className="wrapper">
      <Header />
      <List />
    </div>;
  }
}

превращается в :

// Компонент Wrapper, содержащий "вызовы" компонентов Header и List.
const Wrapper = () => (
  <div className="wrapper">
    <Header />
    <List />
  </div>
);