Автор статьи: Рустем Галиев

IBM Senior DevOps Engineer & Integration Architect. Официальный DevOps ментор и коуч в IBM

Привет Хабр! Сегодня поговорим про основы React: отображение данных в React и передачу данных через props.

Начнем с отображения данных

Компоненты React проявляют себя лучше всего, когда говорят: «Дайте мне данные, и я их нарисую». В этом сценарии мы будем практиковаться в отображении данных, о которых знает компонент. Данные ”отрисовывания” на веб-странице будут включать интерполяцию. Это просто означает получение значения переменной, преобразование его в строку и размещение его в HTML, чтобы веб-страница отобразила его.

Но иногда это немного сложнее; что, если мы хотим отобразить данные в массиве? Что, если мы хотим условно отобразить что-то? К счастью, есть способы сделать обе эти вещи. Давайте взглянем.

Мы получаем данные, интерполируя их. В React это делается с помощью фигурных скобок: {}. Давайте сделаем это в People.js, где мы уже настроились на чтение списка людей из жестко запрограммированных данных.

Создадим и отредактируем src/People.js:

export function People() {
  const people = [
	{ id: 135, first: 'Phoebe', last: 'Buffay', image: '/images/pbuffay.jpg', notes: 'Guitarist. Surrogate mom. Has a smelly cat.' },
	{ id: 225, first: 'Ross', last: 'Geller', image: '/images/rgeller.jpg', notes: 'PhD in Paleontology' },
	{ id: 1043, first: 'Chandler', last: 'Bing', image: '', notes: 'No one is certain what he does for a living. Could he BE more sarcastic?' },
	{ id: 17, first: 'Rachel', last: 'Green', image: '/images/rgreen.jpg', notes: 'Fashion designer' },
  ]

  return (
	<>
  	<section>
    	<img src="image" alt="first" />
    	<h2>Firstname Lastname</h2>
    	<p>Notes</p>
  	</section>
	</>
  )
}

Добавим

const person = people[0];

А теперь давайте отобразим имя этого человека. Измените <h2> с <h2>Firstname Lastname</h2> на <h2>{person.first} {person.last}</h2>

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

Теперь попытаемся сделать то же самое для person.notes и person.image. (Подсказка: используйте свойство src элемента <img>.) Вы поймете, что все сделали правильно, когда обновите вкладку браузера и увидите человека.

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

Отображение нескольких вещей

Теперь мы можем отображать данные из одного объекта, но как отобразить несколько объектов, например, в массиве?

Мы будем перебирать массив, используя метод JavaScript Array.map(). В IDE найдем единственный <section>, где отрисовываем одного человека. Обернем это выражением JavaScript следующим образом:

{people.map(person => //The thing you're repeating)}

Другими словами, помещаем это в строку над <section>

{people.map(person =>

и закрываем его ниже этого </section>:

)}

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

И последнее, ради производительности React требует, чтобы мы предоставляли ключ для каждой повторяющейся вещи. Меняем <section> на это:

<раздел>

к этому:

<section key={person.id}>

Мы научились отображать данные, как отдельные объекты, так и массивы. Но как мы рисуем вещи условно? Что делать, если нет образа для нашего человека? Может быть, мы вообще не рисуем картину. Давайте попробуем сделать так, чтобы это произошло.

Будем снова использовать выражения в нашем JSX. Помните, что это фигурные скобки ({}). В выражение мы поместим условное выражение.

Находим <img> в нашем коде. И делаем его частью условного выражения:

{person.image && <img src={person.image} alt={person.first} />}

Тем самым говорим: «Если у человека есть изображение, покажите <img>».

Другим вариантом было бы использование:

{person.image ? <img src={person.image} alt={person.first} /> : null}

В котором говорится: «Если у человека есть изображение, покажите <img>. В противном случае покажите ноль».

Теперь посмотрим как передать данные между двумя компонентами

Обычно создается компонент React с данными, а затем эти данные передаются в подкомпонент. Например, у вас есть список «виджетов» на более высоком уровне и вы создаете компонент <Widget> для отображения каждого из них. Что ж, вам нужно передать эти данные «виджета» из родительского списка в дочерний, верно?

Давайте попрактикуемся в этом сценарии. У нас будет список людей в App.js, мы передадим его компоненту <People>, а затем пройдемся по компоненту <Person>, чтобы нарисовать каждого человека.

Переключаемся на вкладку IDE и смотрим на src/App.js, вы увидите, что у нас есть множество людей.

import './App.css';
import { People } from './People'
function App() {
  const people = [
	{ id: 135, first: 'Phoebe', last: 'Buffay', image: '/images/pbuffay.jpg', notes: 'Guitarist. Surrogate mom. Has a smelly cat.' },
	{ id: 225, first: 'Ross', last: 'Geller', image: '/images/rgeller.jpg', notes: 'PhD in Paleontology' },
	{ id: 1043, first: 'Chandler', last: 'Bing', image: '/images/cbing.png', notes: 'No one is certain what he does for a living. Could he BE more sarcastic?' },
	{ id: 17, first: 'Rachel', last: 'Green', image: '/images/rgreen.jpg', notes: 'Fashion designer' },
  ]

  return (
	<>
  	<main>
    	<People />
  	</main>
	</>
  );
}

export default App;

Но этот массив необходимо отправить компоненту <People> для отображения. Давайте отправим его через props.

Мы собираемся изменить src/People.js для получения props.

import { Person } from './Person';
let people; // Just to prevent a compile error. Feel free to remove it eventually.

export function People() {

  return (
	<>
  	<h1>All the people</h1>
  	{people?.map(p => <span className="nameOnly">{p.first} {p.last}</span>)}
  	<section className="people">
    	{people?.map(p => <Person />)}
  	</section>
	</>
  )
}

Видите старое определение функции? Измените это:

export function People() {

На это

export function People(props) {

Мы просто готовим его к получению props от родителя. Затем вытащим людей из объекта props. Добавим это внутрь функции People:

let people=props.people;

Далее редактируем src/App.js и находим, где мы размещаем компонент <People>:


<People /> изменим на <People people={people} />

Так мы говорим: «Дайте мне компонент <People> и установите его свойство people в мою переменную people».

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

Теперь давайте пройдем еще один уровень

People.js уже видит всех людей. Но каждому отдельному экземпляру компонента Person нужен объект person.

В IDE отредактируйте src/People.js и найдите, где мы включаем <Person />. Измените его, чтобы передать человека в качестве props:

<Person person={p} />

Теперь мы редактируем дочерний файл src/Person.js. Обратите внимание, как мы пытаемся показать детали для одного человека.

Меняем объявление функции следующим образом: export function Person() {

на

export function Person(props) {

Затем просто вытащите человека из props вот так:

let person = props.person;

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

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

Комментарии (1)