Tutorial

Создание пользовательских компонентов в React

DevelopmentJavaScriptProgramming ProjectReact

Автор выбрал Creative Commons для получения пожертвования в рамках программы Write for DOnations.

Введение

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

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

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

Предварительные требования

Шаг 1 — Настройка проекта React

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

Прежде всего, создайте новый проект. Откройте терминал и запустите в нем следующую команду:

  • npx create-react-app tutorial-03-component

После этого переключитесь в каталог проекта:

  • cd tutorial-03-component

Откройте код App.js в текстовом редакторе:

  • nano src/App.js

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

tutorial-03-component/src/App.js
import React from 'react';
import './App.css';

const displayEmojiName = event => alert(event.target.id);
const emojis = [
  {
    emoji: '😀',
    name: "test grinning face"
  },
  {
    emoji: '🎉',
    name: "party popper"
  },
  {
    emoji: '💃',
    name: "woman dancing"
  }
];

function App() {
  const greeting = "greeting";
  const displayAction = false;
  return(
    <div className="container">
      <h1 id={greeting}>Hello, World</h1>
      {displayAction && <p>I am writing JSX</p>}
      <ul>
        {
          emojis.map(emoji => (
            <li key={emoji.name}>
              <button
                onClick={displayEmojiName}
              >
                <span role="img" aria-label={emoji.name} id={emoji.name}>{emoji.emoji}</span>
              </button>
            </li>
          ))
        }
      </ul>
    </div>
  )
}

export default App;

В этом коде используется синтаксис JSX для использования функции map() в массиве emojis и вывода списка эмодзи как элементов списка <li>. Также данный код прикрепляет события onClick для отображения данных об эмодзи в браузере. Чтобы изучить код более подробно, ознакомьтесь с документом Создание элементов React с помощью JSX, содержащим подробное разъяснение JSX.

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

  • rm src/logo.svg

Далее мы изменим стили. Откройте файл src/App.css:

  • nano src/App.css

Замените его содержимое следующим кодом CSS, чтобы выровнять элементы по центру и изменить шрифт:

tutorial-03-component/src/App.css
.container {
    display: flex;
    flex-direction: column;
    align-items: center;
}

button {
    font-size: 2em;
    border: 0;
    padding: 0;
    background: none;
    cursor: pointer;
}

ul {
    display: flex;
    padding: 0;
}

li {
    margin: 0 20px;
    list-style: none;
    padding: 0;
}

Здесь используется flex для выравнивания по центру главных элементов <h1> и элементов списка. Также здесь удалены стили кнопок по умолчанию и стили <li>, и поэтому эмодзи будут отображаться в одной строке. Более подробную информацию можно найти в документе Создание элементов React с помощью JSX.

Сохраните и закройте файл.

Откройте другое окно терминала в корневом каталоге проекта. Запустите проект с помощью следующей команды:

  • npm start

После запуска команды вы увидите проект в браузере по адресу http://localhost:3000.

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

Вы увидите страницу проекта с надписью Hello, World и тремя эмодзи, указанными вами в файле App.js:

Браузер с эмодзи

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

Шаг 2 — Создание независимого компонента с помощью классов React

Мы запустили проект и теперь можем начать создание собственных компонентов. На этом шаге мы создадим независимый компонент React, расширив базовый класс React Component. Вы создадите новый класс, добавите для него метода и используете функцию render для вывода данных.

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

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

Примечание. Компоненты на базе класса раньше были наиболее популярным способом создания компонентов React. Однако с появлением React Hooks многие разработчики и библиотеки переходят на использование функциональных компонентов.

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

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

  • touch src/Instructions.js

Затем откройте в файл в своем текстовом редакторе:

  • nano src/Instructions.js

Вначале импортируйте компоненты React и класс Component и экспортируйте Instructions:

tutorial-03-component/src/Instructions.js
import React, { Component } from 'react';

export default class Instructions extends Component {}

При импорте React выполнит конвертацию JSX. Component — это базовый класс, который вы расширяете для создания вашего компонента. Вы создали класс с именем вашего компонента (Instructions) и расширили базовый класс Component строкой export. Также вы экспортируете этот класс как класс по умолчанию, используя ключевые слова export default в начале декларации класса.

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

В базовом классе Component имеется несколько методов, которые вы можете использовать в своем собственном классе. Наиболее важный из них — метод render(), который мы будем использовать в этом обучающем модуле. Метод render() возвращает код JSX, который нужно отобразить в браузере.

Для начала добавим небольшое описание приложения в теге <p>:

tutorial-03-component/src/Instructions.js
import React, { Component } from 'react';

export class Instructions extends Component {

  render() {
    return(
      <p>Click on an emoji to view the emoji short name.</p>
    )
  }

}

Сохраните и закройте файл. Пока в браузере не произошло никаких изменений. Это связано с тем, что мы еще не использовали новый компонент. Чтобы использовать компонент, нужно добавить его в другой компонент, связанный с корневым компонентом. В этом проекте <App> является корневым компонентом index.js. Чтобы он отображался в приложении, вам нужно добавить кое-что в компонент <App>.

Откройте src/App.js в текстовом редакторе:

  • nano src/App.js

Вначале вам нужно будет импортировать компонент:

tutorial-03-component/src/App.js
import React from 'react';

import Instructions from './Instructions';

import './App.css';

...

export default App;

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

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

tutorial-03-component/src/App.js
import React from 'react';

import Instructions from './Instructions.js'

...
function App() {
  const greeting = "greeting";
  const displayAction = false;
  return(
    <div className="container">
      <h1 id={greeting}>Hello, World</h1>
      {displayAction && <p>I am writing JSX</p>}
      <Instructions />
      <ul>
        {
          emojis.map(emoji => (
            <li key={emoji.name}>
              <button
                onClick={displayEmojiName}
              >
                <span role="img" aria-label={emoji.name} id={emoji.name}>{emoji.emoji}</span>
              </button>
            </li>
          ))
        }
      </ul>
    </div>
  )
}

export default App;

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

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

Браузер с текстом инструкций

Текст у нас есть, и теперь можно добавить изображение. Загрузите изображение эмодзи с сайта wikimedia и сохраните его в каталоге src под именем emoji.svg с помощью следующей команды:

  • curl -o src/emoji.svg https://upload.wikimedia.org/wikipedia/commons/3/33/Twemoji_1f602.svg

curl отправляет запрос URL, а флаг -o позволяет сохранить файл как src/emoji.svg.

Откройте файл компонента:

  • nano src/Instructions.js

Импортируйте эмодзи и добавьте его в свой компонент с помощью динамической ссылки:

tutorial-03-component/src/Instructions.js
import React, { Component } from 'react';
import emoji from './emoji.svg'

export default class Instructions extends Component {

  render() {
    return(
      <>
        <img alt="laughing crying emoji" src={emoji} />
        <p>Click on an emoji to view the emoji short name.</p>
      </>
    )
  }
}

Обратите внимание, что при импорте нужно указать расширение файла .svg. Во время импорта мы импортируем динамический путь, созданный webpack при компиляции кода. Дополнительную информацию можно найти в документе «Настройка проекта React с помощью приложения Create React».

Вам потребуется закрыть теги <img> и <p> пустыми тегами, чтобы выводился только один элемент.

Сохраните файл. При перезагрузке изображение будет очень большим по сравнению с остальным контентом:

Окно браузера с большим изображением эмодзи

Чтобы уменьшить изображение, нужно будет добавить код CSS и className в пользовательский компонент.

Вначале замените в файле Instructions.js пустые теги на div и присвойте параметру className значение instructions:

tutorial-03-component/src/Instructions.js
import React, { Component } from 'react';
import emoji from './emoji.svg'

export default class Instructions extends Component {

  render() {
    return(
      <div className="instructions">
        <img alt="laughing crying emoji" src={emoji} />
        <p>Click on an emoji to view the emoji short name.</p>
      </div>
    )
  }
}

Сохраните и закройте файл. Откройте файл App.css:

  • nano src/App.css

Создайте правила выбора класса для instructions class selector:

tutorial-03-component/src/App.css
.container {
    display: flex;
    flex-direction: column;
    align-items: center;
}

...

.instructions {
    display: flex;
    flex-direction: column;
    align-items: center;
}

При добавлении отображения стилей flex вы выравниваете img и p по центру с помощью flexbox. Вы изменили направление так, что все содержимое экрана выравнивается по вертикали, с помощью flex-direction: column;. Строка align-items: center; выравнивает элементы по центру экрана.

Теперь элементы выровнены, и вам нужно изменить размер изображения. Задайте для img внутри div значения width и height в 100px.

tutorial-03-component/src/App.css
.container {
    display: flex;
    flex-direction: column;
    align-items: center;
}

...

.instructions {
    display: flex;
    flex-direction: column;
    align-items: center;
}

.instructions img {
    width: 100px;
    height: 100px;
}

Сохраните и закройте файл. Браузер перезагрузится, и вы увидите уменьшенное изображение:

Окно браузера с уменьшенным изображением

Вы создали независимый пользовательский компонент, который можно использовать много раз. Чтобы посмотреть возможности многократного использования, добавьте второй экземпляр в App.js.

Откройте App.js:

  • nano src/App.js

Добавьте в App.js второй экземпляр компонента:

tutorial-03-component/src/App.js
import React from 'react';

import Instructions from './Instructions.js'

...

function App() {
  const greeting = "greeting";
  const displayAction = false;
  return(
    <div className="container">
      <h1 id={greeting}>Hello, World</h1>
      {displayAction && <p>I am writing JSX</p>}
      <Instructions />
      <Instructions />
      <ul>
        {
          emojis.map(emoji => (
            <li key={emoji.name}>
              <button
                onClick={displayEmojiName}
              >
                <span role="img" aria-label={emoji.name} id={emoji.name}>{emoji.emoji}</span>
              </button>
            </li>
          ))
        }
      </ul>
    </div>
  )
}

export default App;

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

Браузер с двумя экземплярами компонента Instructions

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

Пока что удалите лишний тег image. Удалите в текстовом редакторе второй компонент <Instructions /> и сохраните файл:

tutorial-03-component/src/App.js
import React from 'react';

import Instructions from './Instructions.js'

...

function App() {
  const greeting = "greeting";
  const displayAction = false;
  return(
    <div className="container">
      <h1 id={greeting}>Hello, World</h1>
      {displayAction && <p>I am writing JSX</p>}
      <Instructions />
      <ul>
        {
          emojis.map(emoji => (
            <li key={emoji.name}>
              <button
                onClick={displayEmojiName}
              >
                <span role="img" aria-label={emoji.name} id={emoji.name}>{emoji.emoji}</span>
              </button>
            </li>
          ))
        }
      </ul>
    </div>
  )
}

export default App;

Теперь у вас имеется самодостаточный компонент, который вы можете несколько раз добавить в родительский компонент. Данная структура хорошо работает при небольшом количестве компонентов, но есть небольшая проблема. Все файлы перемешаны друг с другом. Изображение для <Instructions> находится в том же каталоге, что и ресурсы для <App>. Также вы сочетаете код CSS для <App> с кодом CSS для <Instructions>.

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

Шаг 3 — Создание удобной для чтения структуры файлов

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

Поскольку у нас имеется независимый компонент, нам нужна файловая структура для группировки соответствующего кода. Сейчас все хранится в одном каталоге. Выведите все элементы из каталога src:

  • ls src/

На экране вы увидите, что все довольно запутанно:

Output
App.css Instructions.js index.js App.js emoji.svg serviceWorker.js App.test.js index.css setupTests.js

Код компонента <App> (App.css, App.js и App.test.js) хранится вместе с кодом корневого компонента (index.css и index.js) и кодом вашего компонента Instructions.js.

React намеренно игнорирует структуру файлов. Он не рекомендует какую-то определенную структуру, и проект может использовать самые разнообразные иерархии файлов. Однако мы рекомендуем немного упорядочить его, чтобы избежать перегрузки корневого каталога компонентами, файлами CSS и изображениями, в которых будет трудно сориентироваться. Кроме того, явное присвоение имен упрощает определение связанных частей проекта. Например, файл изображения Logo.svg вряд ли может быть частью компонента Header.js.

Одна из самых простых структур предполагает создание каталога components, содержащего отдельные каталоги для каждого компонента. Это позволит группировать компоненты отдельно от кода конфигурации (например, serviceWorker) и при этом группировать ресурсы с компонентами.

Создание каталога Components

Для начала создайте каталог с именем components:

  • mkdir src/components

Затем переместите в каталог следующие компоненты и код: App.css, App.js, App.test.js, Instructions.js и emoji.svg:

  • mv src/App.* src/components/
  • mv src/Instructions.js src/components/
  • mv src/emoji.svg src/components/

Здесь мы используем подстановочный символ (*), чтобы выбрать все файлы, начинающиеся с App..

После перемещения кода вы увидите ошибку на терминале, где выполняется npm start.

Output
Failed to compile. ./src/App.js Error: ENOENT: no such file or directory, open 'your_file_path/tutorial-03-component/src/App.js'

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

Для этого откройте файл index.js.

  • nano src/index.js

Измените путь импорта App для импорта из каталога components/.

tutorial-03-component/src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './components/App';
import * as serviceWorker from './serviceWorker';

...

serviceWorker.unregister();

Сохраните и закройте файл. Скрипт обнаружит изменения, и сообщение об ошибке исчезнет.

Теперь компоненты хранятся в отдельном каталоге. По мере усложнения ваших приложений вы можете начать использовать каталоги для служб API, хранилищ данных и утилитарных функций. Отделение кода компонентов будет первым шагом, однако код CSS для компонента Instructions все еще находится в файле App.css. Для логического разделения нужно предварительно переместить компоненты в отдельные каталоги.

Перемещение компонентов в отдельные каталоги

Вначале нужно создать специальный каталог для компонента <App>:

  • mkdir src/components/App

Затем нужно переместить сопутствующие файлы в новый каталог:

  • mv src/components/App.* src/components/App

Вы получите похожее сообщение об ошибке в последнем разделе:

Output
Failed to compile. ./src/components/App.js Error: ENOENT: no such file or directory, open 'your_file_path/tutorial-03-component/src/components/App.js'

В этом случае вам нужно будет обновить две вещи. Вначале нужно будет обновить путь в файле index.js.

Откройте файл index.js:

  • nano src/index.js

Обновите путь импорта App, чтобы он указывал на компонент App в каталоге App.

tutorial-03-component/src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './components/App/App';
import * as serviceWorker from './serviceWorker';

...

serviceWorker.unregister();

Сохраните и закройте файл. Приложение все еще не будет работать. Вы увидите следующее сообщение об ошибке:

Output
Failed to compile. ./src/components/App/App.js Module not found: Can't resolve './Instructions.js' in 'your_file_path/tutorial-03-component/src/components/App'

Поскольку компонент <Instructions> находится не в том же каталоге, что и компонент <App>, вам нужно будет изменить путь импорта. Перед этим создайте каталог для компонента Instructions. Создайте каталог Instructions внутри каталога src/components:

  • mkdir src/components/Instructions

Затем переместите в этот каталог файлы Instructions.js и emoji.svg:

  • mv src/components/Instructions.js src/components/Instructions
  • mv src/components/emoji.svg src/components/Instructions

Мы создали компонент Instructions и теперь можем завершить обновление путей файлов для подключения компонента к приложению.

Обновление путей импорта

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

Откройте App.js:

  • nano src/components/App/App.js

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

tutorial-03-component/src/components/App/App.js
import React from 'react';

import Instructions from '../Instructions/Instructions.js';

import './App.css';

...

export default App;

Сохраните и закройте файл. Теперь вы используете правильные пути для импорта, и ваш браузер обновит экран и выведет приложение.

Окно браузера с уменьшенным изображением

Примечание. Вы также можете вызывать корневой файл в каждом каталоге index.js. Например, вместо src/components/App/App.js вы можете создать файл src/components/App/index.js. Это позволит немного уменьшить строку импорта. Если путь указывает на каталог, при импорте приложение будет искать файл index.js. Для импорта src/components/App/index.js в файл src/index.js нужно использовать команду import ./components/App. Недостатком этого подхода заключается большое количество файлов с одним именем, что может создать сложности в некоторых текстовых редакторах. Это личное решение и решение команды, но лучше всего действовать согласованно.

Разделение кода в общих файлах

Теперь у каждого компонента имеется собственный каталог, но компоненты еще не полностью независимы. Последний шаг заключается в том, чтобы извлечь код CSS для компонента Instructions в отдельный файл.

Для начала создайте файл CSS в каталоге src/components/Instructions:

  • touch src/components/Instructions/Instructions.css

Затем откройте файл CSS в текстовом редакторе:

  • nano src/components/Instructions/Instructions.css

Добавьте код CSS для инструкций, созданный на предыдущем шаге:

tutorial-03-component/src/components/Instructions/Instructions.css
.instructions {
    display: flex;
    flex-direction: column;
    align-items: center;
}

.instructions img {
    width: 100px;
    height: 100px;
}

Сохраните и закройте файл. Затем удалите код CSS для инструкций из файла src/components/App/App.css.

  • nano src/components/App/App.css

Удалите строки, где упоминается .instructions. Итоговый файл будет выглядеть следующим образом:

tutorial-03-component/src/components/App/App.css
.container {
    display: flex;
    flex-direction: column;
    align-items: center;
}

button {
    font-size: 2em;
    border: 0;
    padding: 0;
    background: none;
    cursor: pointer;
}

ul {
    display: flex;
    padding: 0;
}

li {
    margin: 0 20px;
    list-style: none;
    padding: 0;
}

Сохраните и закройте файл. В заключение импортируйте код CSS в файл Instructions.js:

  • nano src/components/Instructions/Instructions.js

Импорт CSS с использованием относительного пути:

tutorial-03-component/src/components/Instructions/Instructions.js
import React, { Component } from 'react';
import './Instructions.css';
import emoji from './emoji.svg'

export default class Instructions extends Component {

  render() {
    return(
      <div className="instructions">
        <img alt="laughing crying emoji" src={emoji} />
        <p>Click on an emoji to view the emoji short name.</p>
      </div>
    )
  }
}

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

Окно браузера с уменьшенным изображением

Еще раз посмотрим на структуру. Вначале идет каталог src/:

  • ls src

У нас имеется корневой компонент index.js и связанный файл CSS index.css рядом с каталогом components/ и служебными файлами serviceWorker.js , setupTests.js и т. д.:

Output
components serviceWorker.js index.css setupTests.js index.js

Теперь войдем в каталог components:

  • ls src/components

Вы увидите в нем отдельный каталог для каждого компонента:

Output
App Instructions

Если вы посмотрите в каждый из этих каталогов, вы найдете там код компонента, код CSS, тестовые файлы и файлы изображений, если они есть.

  • ls src/components/App
Output
App.css App.js App.test.js
  • ls src/components/Instructions
Output
Instructions.css Instructions.js emoji.svg

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

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

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

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

Шаг 4 — Построение функционального компонента

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

Функциональный компонент — это функция JavaScript, возвращающая JSX. Функция не требует расширения и не нужно запоминать никаких специальных методов.

Чтобы превратить <Instructions> в функциональный компонент нужно изменить класс на функцию и удалить метод render, чтобы осталось только одно выражение return.

Для этого вначале откройте Instructions.js в текстовом редакторе.

  • nano src/components/Instructions/Instructions.js

Замените декларацию class декларацией function:

tutorial-03-component/src/components/Instructions/Instructions.js
import React, { Component } from 'react';
import './Instructions.css';
import emoji from './emoji.svg'

export default function Instructions() {
  render() {
    return(
      <div className="instructions">
        <img alt="laughing crying emoji" src={emoji} />
        <p>Click on an emoji to view the emoji short name.</p>
      </div>
    )
  }
}

Удалите импорт { Component }:

tutorial-03-component/src/components/Instructions/Instructions.js
import React from 'react';
import './Instructions.css';
import emoji from './emoji.svg'

export default function Instructions() {

  render() {
    return(
      <div className="instructions">
        <img alt="laughing crying emoji" src={emoji} />
        <p>Click on an emoji to view the emoji short name.</p>
      </div>
    )
  }
}

Удалите метод render(). Теперь вы возвращаете только код JSX.

tutorial-03-component/src/components/Instructions/Instructions.js
import React from 'react';
import './Instructions.css';
import emoji from './emoji.svg'

export default function Instructions() {
  return(
    <div className="instructions">
        <img alt="laughing crying emoji" src={emoji} />
        <p>Click on an emoji to view the emoji short name.</p>
    </div>
  )
}

Сохраните файл. Браузер обновится, и вы увидите страницу такой же, как она выглядела раньше.

Браузер с эмодзи

Вы можете также переписать функцию как стрелочную функцию, используя неявный возврат. Основное отличие заключается в том, что здесь мы теряем тело функции. Также нужно предварительно назначить для функции переменную, а затем экспортировать переменную:

tutorial-03-component/src/components/Instructions/Instructions.js
import React from 'react';
import './Instructions.css';
import emoji from './emoji.svg'

const Instructions = () => (
  <div className="instructions">
    <img alt="laughing crying emoji" src={emoji} />
    <p>Click on an emoji to view the emoji short name.</p>
  </div>
)

export default Instructions;

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

Заключение

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

Понимая концепцию компонентов, вы можете начать рассматривать свои приложения как конструктор, который можно разбирать и собирать. Проекты становятся модульными и взаимозаменяемыми. Способность видеть приложения как набор компонентов — важный шаг в развитии мышления для разработки на React. Если вас интересуют другие обучающие модули по React, ознакомьтесь с нашей страницей тем по React или вернитесь на страницу серии Программирование на React.js.

0 Comments

Creative Commons License