#3 React - пробрасываем данные из парент компонента в чайлд с помощью props

poster
В этом уроке мы разберем такой тип данных в React, как props. Научимся передавать данные из родительской компоненты в дочернюю с помощью props.
Понравилось? Поделитесь с друзьями!
Понравилось?
Поделитесь с друзьями!
Комментарии
Текст видео

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

Давайте попробуем. И у нас будет вполне реальный пример. Мы будем делать хедер с меню.

Создадим новый файл Header.js и скопируем в него App.js и немножко изменим.

import React, { Component } from 'react';

class Header extends Component {
  render() {
    return (
      <div>
        Header
      </div>
    );
  }
}

export default Header;

Импортируем его в App.js. Заодно удалим Dropdown. И вставим Header вместо Dropdown.

import React, { Component } from 'react';

import Header from './Header';

class App extends Component {
  render() {
    return (
      <div>
        <Header />
      </div>
    );
  }
}

export default App;

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

Теперь давайте представим, что мы получаем ссылки для меню от бекенда. Хорошей практикой считается делать один умный компонент на страницу и вкладывать в него тупые компоненты. При условии, что уровень вложености не очень глубокий. Умный компонент может получать данные например от бекенда, а тупые просто получают данные от парента, которые им пробросили и что-то рендерят.

Давайте сделаем наш App умным, а Header и его чайл компоненты тупыми.

Создадим в App массив тестовых данных, как будто мы получили их с бекенда. Создадим меню, которое будет массив обьектов.

const menu = [
  {
    link: '/articles',
    label: 'Articles'
  },
  {
    link: '/contacts',
    label: 'Contacts'
  },
  {
    link: '/posts',
    label: 'Posts'
  }
];

Теперь пробросим их как параметр в Header. Для этого мы просто указываем атрибут items в значением menu.

<Header items={menu} />

Теперь для того, чтобы работать с ними в Header нужно использовать this.props. Давайте напишем console.log в рендер методе

console.log('items', this.props.items);

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

{this.props.items.map((item, index) =>
  <a href={item.link}>{item.label}</a>
)}

Если мы посмотрим в браузер то увидим, что наш массив отрендерился, но у нас есть Warning

warning.js:36 Warning: Each child in an array or iterator should have a unique "key" prop. Check the render method of `Header`.

Он говорит, что каждый елемент внутри массива должен иметь уникальный ключ. Поэтому давайте добавим атрибут key.

{this.props.items.map((item, index) =>
  <a href={item.link} key={index}>{item.label}</a>
)}

Теперь никаких ошибок нет и наши ссылки зарендерились. Если вы хотите пробросить какие-то данные из парент компонента, например, как мы пробрасывали из App в Header, то для этого вам нужно использовать props.

Только зарегистрированные пользователи могут оставлять комментарии.  Войдите, пожалуйста.
Moe Green
6 лет назад
вообще, невозможность в React создать что-либо в компоненте "на всплытие" меня обескураживает. React умеет работать только в одну сторону - на погружение? или я чего-то не знаю\не понимаю?
Moe Green
6 лет назад
забавно получается. вот у меня есть parent component. из него я передаю функцию-метод child component, который лежит на глубину две-три вложенности от parent. и мне приходится "протаскивать" эту функцию через все промежуточные компоненты до целевого child component, чтобы на нем функция срабатывала. как-т коряво и утомительно получается. в vue я могу это выполнить более лаконично, оформив подписку даже двумя способами - $emit или eventBus. Ваши мысли по этому поводу? )
monsterlessons
6 лет назад
Если в двух словах, то Pub/Sub вообще не скейлится для больших проектов и у вас получается 100500 компонент которые непонятно на что подписаны и рандомно себя меняют, что вообще невозможно дебажить. Это именно то, что происходило в бекбоне, когда на нем писали приложения. Именно по этой причине все современные фреймворки делают в виде дерева компонентов. Это позволяет легко прослеживать путь данных от рута до любого уровня вложенности. Наличие PubSub в Vue иначе как хаком и архитектурной ошибкой, которая показывает людям как делать неправильно я назвать не могу. Ваша проблема решается любой библиотекой с стейтом типа redux, где вы можете на любом уровне обращаться к нужным вам данным и емитить экшены. Для Vue это будет библиотека Vuex.
Moe Green
6 лет назад
Круто! За такой коммит - однозначный Like! )
Аношко Антон
6 лет назад
Лайк
BaD_ AppLE_
7 лет назад
вопрос, а как быть, если я, как в меню хедера, хочу с помощью цикла выводить данные в небольшой блок, то есть, чтобы помимо ссылки в .map() было бы еще что-то, например абзац текста(скажем я делаю интернет магазин, а данные получаю в JSON и 1 объект- 1 млок с картинкойб названием и ценой товата), я попробовал вывести индексы еще и в h1, так для эксперимента, и постоянно выводилась ошибка, то же самое и если содержимое вункции обернуть в {}, хотя по логике их присутствие вообще никак не должно мещать
monsterlessons
7 лет назад
Простите, но без примера кода не очень понятно что вы хотите сделать. Вы можете вывестить что угодно в компоненте const Test = () => ( <div> {someText} more Text {items.map(item, index) => ( <div key={index}>{item}</div> )} </div> )
BaD_ AppLE_
7 лет назад
спасибо за ответ, я разобрался, не выводилось несколько елементов, потому что при нескольких строках return, который абстрагировали не применяется, надо было явно написать return и все сработало)))