Главная » React & Redux » Картинка с подрисуночной подписью: создаём более сложные компоненты React.

Картинка с подрисуночной подписью: создаём более сложные компоненты React.


05.09.2021, 09:05

Это тот результат, который должен получиться в итоге

Определяем основные визуальные элементы

Разбираем на отдельные элементы:


Получаем три основных элемента, которые, собираясь воедино, дают решение задачи

Зададим элемент-контейнер, в который будем выводить наш результат

Код

      <div id="container"></div>

После него размещаем заготовку скрипта:

Код

     <div id="container"></div>

     <script type="text/babel">
         ReactDOM.render(
             <div>
                  
             </div>,
             document.querySelector('#container')
         );
     </script>

Что сейчас представляет собой код? В данном случае, всего лишь визуализация пустого элемента div в выбранный блок-контейнер с id = container.

Создаём компоненты на основе выбранных визуальных элементов

Так как визуальных элементов получилось три, создаём три новых компонента, задаём им имена Card, Label, Photos, размещаем до функции ReactDOM.render

Код

         class Photos extends React.Component {
             render() {
                 return (
                     <br/>
                 );
             }
         }

         class Label extends React.Component {
             render() {
                 return (
                     <br/>
                 );
             }
         }

         class Card extends React.Component {
             render() {
                 return (
                     <br/>
                 );
             }
         }

Сейчас они пустые и функция render() в каждом из них возвращает только лишь элемент br (просто заготовка)

Компонент Card - контейнер для двух других компонентов: Label и Photos

Внутри функции render() компонента создаём объект cardStyle, свойства которого описывают как будет выглядеть на странице блок-контейнер, в котором будут размещаться картинка и подрисуночная подпись.

Код

         class Card extends React.Component {
             render() {
                 let cardStyle = {
                     height: 250,
                     width: 300,
                     padding: 0,
                     backgroundColor: "#2C3A47",
                     boxShadow: "0px 0px 5px #666"
                 };

                 return (
                     <div style = {cardStyle}>
                            
                     </div>
                 );
             }
         }

Блок-контейнер возвращается функцией return(), при этом его атрибуту style присваивается объект cardStyle с его свойствами.

Чтобы увидеть блок-контейнер на странице, нужно поместить его в модель DOM, для этого используем функцию ReactDOM.render()

Код

         ReactDOM.render(
             <div>
                 <Card/>
             </div>,
             document.querySelector('#container')
         );


Блок-контейнер появился на странице

Компонент Photos

Опускаемся вглубь иерархии элементов и переходим к компоненту Photos, отвечающему за визуализацию изображения.

Создадим объект photoStyle внутри функции render() этого компонента:

Код

         class Photos extends React.Component {
             render() {
                 let photoStyle = {
                     width: 300,
                     height: 188,
                     backgroundImage: "url(img/lamborgini.jpg)",
                     backgroundPosition: 'center',
                     backgroundSize: 'cover',
                     backgroundRepeat: 'no-repeat'
                 };

                 return (
                     <div style = {photoStyle}>

                     </div>
                 );

             };

         }

И точно также, как и у предыдущего компонента, у нас будет возвращаться блок div, атрибуту style которого присваивается созданный внутри компонента объект с заданными свойствами.

Но компонент Photos вызовем на этот раз не с помощью функции ReactDOM.render(), а непосредственно изнутри компонента Card

Код

         class Card extends React.Component {
             render() {
                 let cardStyle = {
                     height: 250,
                     width: 300,
                     padding: 0,
                     backgroundColor: "#2C3A47",
                     boxShadow: "0px 0px 5px #666"
                 };

                 return (
                     <div style = {cardStyle}>
                         <Photos/>   
                     </div>
                 );
             }
         }


Изображение появилось внутри блока-контейнера

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

Компонент Label

Остался последний компонент, отвечающий за визуализацию подрисуночной подписи.

Создаём внутри него объект labelStyle и добавляем ему свойства, возвращаемому элементу p через его атрибут style присваиваем созданный объект:

Код

         class Label extends React.Component {
             render() {
                 let labelStyle = {
                     fontFamily: "sans-serif",
                     fontWeight: "bold",
                     color: "#dcdde1",
                     height: 32,
                     padding: 15,
                     margin: 0
                 };
                 return(
                     <p style = {labelStyle}>Lamborgini</p>
                 );
             }
         }

Этот компонент вызываем также изнутри компонента Card сразу после вызова компонента Photos:

Код

         class Card extends React.Component {
             render() {
                 let cardStyle = {
                     height: 250,
                     width: 300,
                     padding: 0,
                     backgroundColor: "#2C3A47",
                     boxShadow: "0px 0px 5px #666"
                 };

                 return (
                     <div style = {cardStyle}>
                         <Photos/>
                         <Label/>
                     </div>
                 );
             }
         }


Получили результат, задача решена

Кстати, если сначала вызвать компонент Label, а уже затем Photos, то подрисуночная подпись окажется сверху, а картинка под ней

Передача свойств

Для компонента Label, отвечающего за вывод подрисуночной подписи, в его объекте сейчас жёстко задан цвет текста:

Код

         class Label extends React.Component {
             render() {
                 let labelStyle = {
                     fontFamily: "sans-serif",
                     fontWeight: "bold",
                     color: "#dcdde1", /* Жестко задан цвет текста */
                     height: 32,
                     padding: 15,
                     margin: 0
                 };
                 return(
                     <p style = {labelStyle}>Lamborgini</p>
                 );
             }
         }

Как избавиться от этой жёсткой привязки?

Вместо конкретного значения указываем имя свойства (придумываем сами, я назвал свойство textColor) и с помощью this.props получаем к нему доступ:

Код

         class Label extends React.Component {
             render() {
                 let labelStyle = {
                     fontFamily: "sans-serif",
                     fontWeight: "bold",
                     color: this.props.textColor, /* убираем жёсткую привязку цвета */
                     height: 32,
                     padding: 15,
                     margin: 0
                 };
                 return(
                     <p style = {labelStyle}>Lamborgini</p>
                 );
             }
         }

Редактируем вызов компонента Label, который производится изнутри компонента Card:

Код

                 return (
                     <div style = {cardStyle}>
                         <Photos/>
                         <Label textColor = {this.props.textColor}/>
                     </div>
                 );

Теперь остаётся вызвать через ReactDOM.render() компонент Card и при этом задать нужное значение свойству textColor:

Код

         ReactDOM.render(
             <div>
                 <Card textColor = "#fbc531"/>
             </div>,
             container
         );


Цвет текста подрисуночной надписи сменился на жёлтый, это стало возможным за счёт передачи свойства и его значения дочернему компоненту




Код

<script type="text/babel">
         let container = document.querySelector('#container');

         class Photos extends React.Component {
             render() {
                 let photoStyle = {
                     width: 300,
                     height: 188,
                     backgroundImage: "url(img/lamborgini.jpg)",
                     backgroundPosition: 'center',
                     backgroundSize: 'cover',
                     backgroundRepeat: 'no-repeat'
                 };

                 return (
                     <div style = {photoStyle}>

                     </div>
                 );

             };

         }

         class Label extends React.Component {
             render() {
                 let labelStyle = {
                     fontFamily: "sans-serif",
                     fontWeight: "bold",
                     color: this.props.textColor, /* убираем жёсткую привязку цвета */
                     height: 32,
                     padding: 15,
                     margin: 0
                 };
                 return(
                     <p style = {labelStyle}>Lamborgini</p>
                 );
             }
         }

         class Card extends React.Component {
             render() {
                 let cardStyle = {
                     height: 250,
                     width: 300,
                     padding: 0,
                     backgroundColor: "#2C3A47",
                     boxShadow: "0px 0px 5px #666"
                 };

                 return (
                     <div style = {cardStyle}>
                         <Photos/>
                         <Label textColor = {this.props.textColor}/>
                     </div>
                 );
             }
         }

         ReactDOM.render(
             <div>
                 <Card textColor = "#fbc531"/>
             </div>,
             container
         );
     </script>


КОММЕНТАРИИ (0)