[Перевод] Учебный курс по React, часть 4: родительские и дочерние компоненты

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

image

→ Часть 1: обзор курса, причины популярности React, ReactDOM и JSX
→ Часть 2: функциональные компоненты
→ Часть 3: файлы компонентов, структура проектов
→ Часть 4: родительские и дочерние компоненты

Занятие 9. Родительские и дочерние компоненты


→ Оригинал

Сегодня мы поговорим о родительских и дочерних компонентах. Использование подобных конструкций сделает наше приложение гораздо более сложным, чем в случае, когда в нём был всего один компонент, выводимый в DOM, такой, как MyInfo. Вместо этой простой структуры в приложении может присутствовать сложная иерархия компонентов, которая, в итоге, преобразуется в JSX-элементы.

Начнём с уже знакомого вам шаблона приложения. Для того чтобы вспомнить пройденное, можете, по памяти, в пустом файле index.js, написать код для вывода на страницу заголовка первого уровня с текстом Hello World! средствами React. Вот как может выглядеть подобный код:

import React from "react"
import ReactDOM from "react-dom"

ReactDOM.render(
  

Hello World!

, document.getElementById("root") )


В прошлый раз там, где в вышеприведённом коде находится описание элемента

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

import React from "react"
import ReactDOM from "react-dom"

ReactDOM.render(
  ,
  document.getElementById("root")
)


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

import React from "react"
import ReactDOM from "react-dom"

import App from "./App"

ReactDOM.render(
  ,
  document.getElementById("root")
)


Но такой код всё ещё остаётся нерабочим. Нам нужен файл компонента App (App.js), расположенный в той же папке, что и index.js. Именно к такому файлу мы обращаемся в команде импорта import App from "./App". Напомним, что имена компонентов React записываются в верблюжьем стиле и начинаются с заглавной буквы. Создадим нужный нам файл и опишем в нём компонент App. Попытайтесь сделать это самостоятельно. А именно — напишите код, благодаря которому компонент App выведет на страницу текст Hello again.

Вот как выглядит этот код:

import React from "react"

function App(){
  return (
    

Hello again

) } export default App


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

import React from "react"

function App(){
  return (
    

Hello a third time!

  • Thing 1
  • Thing 2
  • Thing 3
) } export default App


Возможно, сейчас мы решим, что то, что формируется средствами компонента App, должно представлять собой некий веб-сайт. У него будет навигационный блок (

) и область основного содержимого (
). Это решение приведёт к формированию следующего кода:

import React from "react"

function App(){
  return (
    

This is where most of my content will go...

) } export default App


Вот как всё это будет выглядеть в браузере.

9f305772f1ea16a69d4134a2075d914d.png


Приложение в браузере

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

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

Взгляните на эту схему для того, чтобы лучше разобраться в том, о чём идёт речь.

520ee4a6159ef6a9b4f66a68752a3d3b.png


Компонент App выводит компонент MyInfo, выводящий элемент

Тут мы выводим на страницу компонент App. При этом компонент App решает вывести ещё один компонент — MyInfo. А уже компонент MyInfo выводит некий JSX-элемент. Обратите внимание на разницу между понятиями «компонент» и «элемент». Элементы — это сущности, которые превращаются в обычный HTML-код. Так, в элементе, представленном в нижней части схемы, используется простой тег

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

Вы могли слышать о том, что DOM (Document Object Model, объектная модель документа) часто называют «деревом». Корневым элементом этого дерева является элемент . В нашем случаем корневым элементом дерева, представленного на схеме, является компонент App. Возможности этого компонента не ограничиваются выводом другого компонента, MyInfo в нашем случае. Он может, например, вывести ещё один компонент, представляющий собой «подвал», нижнюю часть страницы. Скажем, этот компонент будет носить имя AwesomeFooter.

41528a64a1dad7cfd3c2bf18dadaf0be.png


Компонент App выводит два компонента

Этот компонент, в свою очередь, может вывести элемент

, который будет содержать HTML-код нижней части страницы.

Если у нас имеется «подвал» страницы, то она может содержать и «шапку», оформляющую её верхнюю часть.

d4374efc53b9e85ca38991b5e9cc4cf0.png


Компонент App выводит три компонента

Верхняя часть страницы представлена на нашей схеме компонентом AwesomeHeader. Такие имена этим компонентам даны для того, чтобы не путать их с элементами. Компонент AwesomeHeader, как и компонент App, может выводить не только JSX-разметку, но и другие компоненты. Например, это может быть компонент NavBar, представляющий собой навигационную панель, и компонент Logo, выводящий логотип. А эти компоненты уже выведут обычные элементы — такие, как  и