🐒 ΠšΠ°Ρ€ΠΊΠ°ΡΠ½Ρ‹Π΅ экраны: рСализация Π² React

ΠšΠ°Ρ€ΠΊΠ°ΡΠ½Ρ‹Π΅ экраны - ΠΎΠ΄ΠΈΠ½ ΠΈΠ· самых ΠΏΠΎΠ»Π΅Π·Π½Ρ‹Ρ… UX-ΠΏΠ°Ρ‚Ρ‚Π΅Ρ€Π½ΠΎΠ². ДобавляСм ΠΈΡ… Π² ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ React с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ React Loading Skeleton.

ΠŸΡ€ΠΎΡ„Π΅ΡΡΠΈΠΎΠ½Π°Π»Ρ‹ Π² области UI/UX ΡƒΡ‚Π²Π΅Ρ€ΠΆΠ΄Π°ΡŽΡ‚, Ρ‡Ρ‚ΠΎ Π²Π°ΠΆΠ½ΠΎ ΡΠΎΡ…Ρ€Π°Π½ΡΡ‚ΡŒ Π·Π°ΠΈΠ½Ρ‚Π΅Ρ€Π΅ΡΠΎΠ²Π°Π½Π½ΠΎΡΡ‚ΡŒ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ, ΠΏΠΎΠΊΠ° ΠΎΠ½ΠΈ ΠΎΠΆΠΈΠ΄Π°ΡŽΡ‚ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚Π° Π½Π° страницу.

Π’Ρ€Π°Π΄ΠΈΡ†ΠΈΠΎΠ½Π½ΠΎ для этого Π² Π²Π΅Π±Π΅ использовались спиннСры ΠΈ Π»ΠΎΠ°Π΄Π΅Ρ€Ρ‹. Π­Ρ‚ΠΎ Ρ…ΠΎΡ€ΠΎΡˆΠΈΠΉ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄, вСдь анимированная ΠΈΠΊΠΎΠ½ΠΊΠ° Ρ‡Π΅Ρ‚ΠΊΠΎ Π³ΠΎΠ²ΠΎΡ€ΠΈΡ‚ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŽ: ΠΏΡ€ΠΎ вас Π½Π΅ Π·Π°Π±Ρ‹Π»ΠΈ, процСсс ΠΈΠ΄Π΅Ρ‚. Однако Π² соврСмСнных условиях ΠΎΠ½ ΡƒΠΆΠ΅ нСсколько устарСл. Π§Π΅Π»ΠΎΠ²Π΅ΠΊ ΠΏΠΎΠ½ΠΈΠΌΠ°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ происходит, Π½ΠΎ ΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ Π½Π° двиТущиСся Ρ‚ΠΎΡ‡ΠΊΠΈ довольно скучно. ΠšΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΎΠ±ΠΎΡ€ΠΎΡ‚ спиннСра добавляСт раздраТСния.

На смСну Π»ΠΎΠ°Π΄Π΅Ρ€Π°ΠΌ ΠΏΡ€ΠΈΡˆΠ»ΠΈ "каркасныС" экраны (skeleton screens), ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π½Π΅ просто "тянут врСмя", Π½ΠΎ ΠΈ Π»ΡƒΡ‡ΡˆΠ΅ ΠΎΠ±ΠΎΠ·Π½Π°Ρ‡Π°ΡŽΡ‚ прогрСсс Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ, ΡƒΠΌΠ΅Π½ΡŒΡˆΠ°Ρ Π½Π΅Π³Π°Ρ‚ΠΈΠ²Π½Ρ‹Π΅ ощущСния ΡŽΠ·Π΅Ρ€Π° (loading-time frustration). Π”Ρ€ΡƒΠ³ΠΈΠΌΠΈ словами, ΡΠΎΠ·Π΄Π°ΡŽΡ‚ иллюзию Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎ ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚ Π²ΠΎΡ‚-Π²ΠΎΡ‚ появится.

БСгодня ΠΌΡ‹ Π±ΡƒΠ΄Π΅ΠΌ Ρ€Π°Π·Π±ΠΈΡ€Π°Ρ‚ΡŒΡΡ, ΠΊΠ°ΠΊ ΠΈΡ… Π΄Π΅Π»Π°Ρ‚ΡŒ Π² React-прилоТСниях.

Π Π°Π·Π½ΠΈΡ†Π° ΠΌΠ΅ΠΆΠ΄Ρƒ интСрфСйсом с Π»ΠΎΠ°Π΄Π΅Ρ€ΠΎΠΌ ΠΈ каркасным экраном

Π“Π»ΠΎΠ±Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ погруТСния Π² основы CSS, JS ΠΈΠ»ΠΈ React Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚, поэтому Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ смСло Ρ‡ΠΈΡ‚Π°Ρ‚ΡŒ дальшС, Π΄Π°ΠΆΠ΅ Ссли Π½Π΅ ΡΠ²Π»ΡΠ΅Ρ‚Π΅ΡΡŒ экспСртом Π² этих тСхнологиях.

Π§Ρ‚ΠΎ Ρ‚Π°ΠΊΠΎΠ΅ каркасныС экраны?

ΠšΠ°Ρ€ΠΊΠ°ΡΠ½Ρ‹ΠΉ, ΠΈΠ»ΠΈ скСлСтный, экран – Ρ€Π°Π·Π½ΠΎΠ²ΠΈΠ΄Π½ΠΎΡΡ‚ΡŒ интСрфСйса, которая Π½Π΅ содСрТит Ρ€Π΅Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚Π°. Π’Π°ΠΊΠΎΠΉ UI повторяСт "Π½Π°ΡΡ‚ΠΎΡΡ‰ΡƒΡŽ" Ρ€Π°Π·ΠΌΠ΅Ρ‚ΠΊΡƒ страницы, Π½ΠΎ вмСсто ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚Π½Ρ‹Ρ… Π΅Π΄ΠΈΠ½ΠΈΡ† – тСкста, ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ, ΠΊΠ°Ρ€Ρ‚ΠΎΡ‡Π΅ΠΊ, Π±Π»ΠΎΠΊΠΎΠ² – ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ "Π·Π°Π³Π»ΡƒΡˆΠΊΠΈ", схоТиС с Π½ΠΈΠΌΠΈ ΠΏΠΎ Ρ„ΠΎΡ€ΠΌΠ΅ (ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ сСрыС Π»ΠΈΠ½ΠΈΠΈ ΠΈ ΠΏΡ€ΡΠΌΠΎΡƒΠ³ΠΎΠ»ΡŒΠ½ΠΈΠΊΠΈ, Π° Ρ‚Π°ΠΊΠΆΠ΅ ΠΈΡ… Π³Ρ€ΡƒΠΏΠΏΡ‹). Когда ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚ загруТаСтся ΠΈ Π·Π°Π½ΠΈΠΌΠ°Π΅Ρ‚ своС мСсто Π² ΠΌΠ°ΠΊΠ΅Ρ‚Π΅, Π·Π°Π³Π»ΡƒΡˆΠΊΠΈ ΠΈΡΡ‡Π΅Π·Π°ΡŽΡ‚. Π­Ρ‚ΠΎΡ‚ ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ выглядит Π½Π΅ Ρ‚Π°ΠΊΠΈΠΌ Ρ€Π΅Π·ΠΊΠΈΠΌ, ΠΊΠ°ΠΊ ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ ΠΌΠ΅ΠΆΠ΄Ρƒ чистой страницСй ΠΈ Π·Π°ΠΏΠΎΠ»Π½Π΅Π½Π½ΠΎΠΉ тСкстом.

Π”Ρ€ΡƒΠ³ΠΈΠΌΠΈ словами, это занятый плСйсхолдСрами вмСсто Ρ€Π΅Π°Π»ΡŒΠ½Ρ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ… "скСлСт" страницы.

Π’Π°ΠΊ ΠΊΠ°ΠΊ скСлСтный UI Π½Π°ΠΏΠΎΠΌΠΈΠ½Π°Π΅Ρ‚ настоящий, ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ Π²ΠΈΠ΄ΠΈΡ‚ структуру страницы Π΄Π°ΠΆΠ΅ Π±Π΅Π· ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚Π°, ΠΈ Ρƒ Π½Π΅Π³ΠΎ создаСтся Π²ΠΏΠ΅Ρ‡Π°Ρ‚Π»Π΅Π½ΠΈΠ΅, Π±ΡƒΠ΄Ρ‚ΠΎ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠ° ΠΈΠ΄Π΅Ρ‚ быстрСС – ΠΏΠΎ ΠΊΡ€Π°ΠΉΠ½Π΅ΠΉ ΠΌΠ΅Ρ€Π΅, Ρ‡Ρ‚ΠΎ ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ этап Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ ΡƒΠΆΠ΅ ΠΏΡ€ΠΎΡˆΠ΅Π».

ΠšΠ°Ρ€ΠΊΠ°ΡΠ½Ρ‹Π΅ экраны ΠΎΡ‚Π»ΠΈΡ‡Π½ΠΎ ΡΠΎΡ‡Π΅Ρ‚Π°ΡŽΡ‚ΡΡ с Ρ‚Π΅Ρ…Π½ΠΈΠΊΠΎΠΉ Π»Π΅Π½ΠΈΠ²ΠΎΠΉ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ: постСпСнноС появлСниС элСмСнтов выглядит Π±ΠΎΠ»Π΅Π΅ СстСствСнным, ΠΊΠΎΠ³Π΄Π° ΡƒΠΆΠ΅ ΠΎΠΆΠΈΠ΄Π°Π΅Ρ‚ ΠΈΡ….

Π”Ρ€ΡƒΠ³ΠΈΠ΅ названия Ρ‚Π΅Ρ…Π½ΠΈΠΊΠΈ:

  • ΠΏΡ€ΠΈΠ·Ρ€Π°Ρ‡Π½Ρ‹Π΅ элСмСнты (ghost elements),
  • Π·Π°ΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΠΈ ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚Π° (content placeholders),
  • Π·Π°Π³Ρ€ΡƒΠ·Ρ‡ΠΈΠΊΠΈ ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚Π° (content loaders).

Π­Ρ‚ΠΈΠΌ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΠΎΠΌ ΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ ΠΌΠ½ΠΎΠ³ΠΈΠ΅ сайты, Π² Ρ‚ΠΎΠΌ числС ΠΏΠΎΡ€Ρ‚Π°Π»Ρ‹ ΠΊΡ€ΡƒΠΏΠ½Ρ‹Ρ… тСхнологичСских ΠΊΠΎΠΌΠΏΠ°Π½ΠΈΠΉ: Blockchain.com, YouTube, Facebook, Medium.

Π˜Π½Ρ‚Π΅Ρ€Ρ„Π΅ΠΉΡ Blockchain.com с частично ΠΏΠΎΠ΄Π³Ρ€ΡƒΠΆΠ΅Π½Π½Ρ‹ΠΌ ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚ΠΎΠΌ. Для прСдставлСния Π³Ρ€Π°Ρ„ΠΈΠΊΠΎΠ² Ρ‚Π°ΠΊΠΆΠ΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ скСлСтный плСйсхолдСр.
ΠšΠ°Ρ€ΠΊΠ°ΡΠ½Ρ‹ΠΉ экран Π½Π° сайтС medium
Главная страница сайта LinkedIn Π² 2018 Π΄ΠΎ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚Π°

Π’ΠΈΠΏΡ‹ каркасных экранов

ΠšΠ°Ρ€ΠΊΠ°ΡΠ½Ρ‹Π΅ экраны Π±Ρ‹Π²Π°ΡŽΡ‚ Ρ€Π°Π·Π½Ρ‹ΠΌΠΈ. Π‘Π°ΠΌΡ‹Π΅ популярныС – это тСкстовыС ΠΈ графичСскиС (Ρ†Π²Π΅Ρ‚Π½Ρ‹Π΅) Π·Π°ΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΠΈ.

ВСкстовыС ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ Ρ‡Π°Ρ‰Π΅ всСго, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ ΠΎΠ½ΠΈ максимально просты Π² Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ. Π Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΡƒ Π½Π΅ Π½ΡƒΠΆΠ½ΠΎ Π·Π½Π°Ρ‚ΡŒ особСнности Ρ€Π΅Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚Π°, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π·Π°ΠΌΠ΅Π½ΠΈΡ‚ΡŒ Π΅Π³ΠΎ Π·Π°ΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»Π΅ΠΌ.

ГрафичСскиС каркасы слоТнСС – ΠΎΠ½ΠΈ зависят ΠΎΡ‚ ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚Π°, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π·Π°ΠΌΠ΅Ρ‰Π°ΡŽΡ‚, ΠΈ Π²ΡΡ‚Ρ€Π΅Ρ‡Π°ΡŽΡ‚ΡΡ Ρ€Π΅ΠΆΠ΅.

Π“ΠΎΡ‚ΠΎΠ²Ρ‹Π΅ Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ

Для быстрой Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΏΠ°Ρ‚Ρ‚Π΅Ρ€Π½Π° каркасных экранов Π² вашСм ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΈ ΠΌΠΎΠΆΠ½ΠΎ Π²ΠΎΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ Π³ΠΎΡ‚ΠΎΠ²Ρ‹ΠΌΠΈ Ρ€Π΅ΡˆΠ΅Π½ΠΈΡΠΌΠΈ. Для React ΠΎΠ½ΠΈ, ΠΊΠΎΠ½Π΅Ρ‡Π½ΠΎ, Ρ‚ΠΎΠΆΠ΅ Π΅ΡΡ‚ΡŒ. Рассмотрим ΠΏΠ°Ρ€ΠΎΡ‡ΠΊΡƒ для ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π°.

React Placeholder

Π Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΉ: buildo/react-placeholder

Π—Π°Π³Ρ€ΡƒΠ·ΠΊΠ° ΠΏΠ°ΠΊΠ΅Ρ‚Π°:

npm install --save react-placeholder

Достоинства

  • ΠŸΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ΡΡ ΠΏΡƒΠ»ΡŒΡΠΈΡ€ΡƒΡŽΡ‰Π°Ρ анимация (создаСт эффСкт двиТСния Π½Π° элСмСнтах-плСйсхолдСрах).
  • API Π½Π° основС ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ².

НСдостатки

  • ΠšΠ°Ρ€ΠΊΠ°ΡΠ½Ρ‹Π΅ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡŽΡ‚ΡΡ ΠΏΠΎ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ, поэтому ΠΏΡ€ΠΈ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΈ стилСй ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π° ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠΎΡ‚Ρ€Π΅Π±ΠΎΠ²Π°Ρ‚ΡŒΡΡ ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅ каркаса.
  • ΠšΡ€ΠΈΠ²Π°Ρ обучСния Π½Π΅Π»ΠΈΠ½Π΅ΠΉΠ½Π°, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ Π΅ΡΡ‚ΡŒ мноТСство ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ² для Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Ρ… случаСв использования.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ создания скСлСтного ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π° с использованиСм react-placeholder:

import { TextBlock, RectShape } from 'react-placeholder/lib/placeholders';
import ReactPlaceholder from 'react-placeholder';

const GhostPlaceholder = () => (
  <div className='my-placeholder'>
    <RectShape color='gray' style={{width: 25, height: 70}} />
    <TextBlock rows={6} color='blue'/>
  </div>
);
<ReactPlaceholder ready={ready} customPlaceholder={<GhostPlaceholder />}>
  <MyComponent />
</ReactPlaceholder>

Π—Π° созданиС каркасного плСйсхолдСра ΠΎΡ‚Π²Π΅Ρ‡Π°Π΅Ρ‚ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ ReactPlaceholder. Он просто ΠΎΠ±ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅Ρ‚ Π½ΡƒΠΆΠ½Ρ‹ΠΉ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ прилоТСния Π² Ρ€ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΡΠΊΠΈΠΉ Ρ‚Π΅Π³. Π’ΠΈΠ·ΡƒΠ°Π»ΡŒΠ½ΠΎΠ΅ прСдставлСниС ΠΌΡ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΡΠΎΠ±Ρ€Π°Ρ‚ΡŒ сами ΠΈΠ· доступных элСмСнтов ΠΈ Ρ„ΠΎΡ€ΠΌ ΠΈ ΠΏΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ Π² Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚ customPlaceholder.

Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ для этого Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½Ρ‹ΠΉ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ GhostPlaceholder. Π’Π½ΡƒΡ‚Ρ€ΠΈ Π½Π΅Π³ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ элСмСнты TextBlock (Π±Π»ΠΎΠΊ тСкста) ΠΈ RectShape (ΠΏΡ€ΡΠΌΠΎΡƒΠ³ΠΎΠ»ΡŒΠ½ΠΈΠΊ), ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Π΅ ΠΈΠ· react-placeholder/lib/placeholder.

ВсС плСйсхолдСры ΠΌΠΎΠΆΠ½ΠΎ Π½Π°ΡΡ‚Ρ€Π°ΠΈΠ²Π°Ρ‚ΡŒ Ρ‡Π΅Ρ€Π΅Π· Ρ‚.Π½. пропсы. НапримСр, Π·Π°Π΄Π°Ρ‚ΡŒ Ρ†Π²Π΅Ρ‚ ΠΈ Ρ€Π°Π·ΠΌΠ΅Ρ€ (количСство рядов тСкста) для тСкстового Π±Π»ΠΎΠΊΠ°.

Π§Ρ‚ΠΎΠ±Ρ‹ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ, ΠΊΠΎΠ³Π΄Π° ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Ρ‚ΡŒ каркас, Π° ΠΊΠΎΠ³Π΄Π° ΡƒΠΆΠ΅ ΠΏΠΎΠ΄ΡŠΠ΅Ρ…Π°Π» ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ Π±ΡƒΠ»Π΅Π²ΠΎ свойство ready ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π° ReactPlaceholder.

Π‘ΠΎΠ»ΡŒΡˆΠ΅ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ Π²Ρ‹ Π½Π°ΠΉΠ΄Π΅Ρ‚Π΅ Π² Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ модуля.

React Loading Skeleton

Π Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΉ: dvtng/react-loading-skeleton

Π—Π°Π³Ρ€ΡƒΠ·ΠΊΠ° ΠΏΠ°ΠΊΠ΅Ρ‚Π°:

npm install --save react-loading-skeleton

Достоинства

  • Основан Π½Π° API, Π΅ΡΡ‚ΡŒ ΠΎΠ΄ΠΈΠ½ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚, кастомизируСмый Ρ‡Π΅Ρ€Π΅Π· пропсы.
  • МоТно ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΊΠ°ΠΊ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΉ скСлСтный ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚, Ρ‚Π°ΠΊ ΠΈ прямо Π²Π½ΡƒΡ‚Ρ€ΠΈ Π΄Ρ€ΡƒΠ³ΠΎΠ³ΠΎ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π°.
  • ΠŸΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ Ρ‚Π΅ΠΌΡ‹ ΠΈ ΠΏΡƒΠ»ΡŒΡΠΈΡ€ΡƒΡŽΡ‰ΡƒΡŽ Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΡŽ.

НСдостатки

  • ΠžΡ‚Π»ΠΈΡ‡Π½ΠΎ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΠΈΡ‚ для простых плСйсхолдСров, Π½ΠΎ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° слоТных каркасов ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ Π·Π°Ρ‚Ρ€ΡƒΠ΄Π½Π΅Π½Π°.
  • НаличиС ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ скСлСтного ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π° ΠΌΠΎΠΆΠ΅Ρ‚ Π·Π°Ρ‚Ρ€ΡƒΠ΄Π½ΠΈΡ‚ΡŒ Π΅Π³ΠΎ обслуТиваниС ΠΏΡ€ΠΈ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΈ Π΄ΠΈΠ·Π°ΠΉΠ½Π°.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ создания скСлСтного ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π° с использованиСм react-loading-skeleton:

import Skeleton, { SkeletonTheme } from "react-loading-skeleton";

const SkeletonComponent = () => (
  <SkeletonTheme color="#202020" highlightColor="#444">
    <section>
      <Skeleton height={50} width={50} />
    </section>
  </SkeletonTheme>
);

Π—Π΄Π΅ΡΡŒ ΠΌΡ‹ ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΡƒΠ΅ΠΌ основной ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ Skeleton ΠΈ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ Ρ‚Π΅ΠΌΡ‹ SkeletonTheme ΠΈΠ· модуля.

Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½Ρ‹ΠΉ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ SkeletonComponent. SkeletonTheme слуТит ΠΎΠ±Π΅Ρ€Ρ‚ΠΊΠΎΠΉ для всСго элСмСнта ΠΈ ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ Π² пропсах Ρ†Π²Π΅Ρ‚Π° (color, highlightColor), ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ слСдуСт ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π² ΠΎΡ„ΠΎΡ€ΠΌΠ»Π΅Π½ΠΈΠΈ плСйсхолдСров ΠΈ создании эффСктов. Π’Π½ΡƒΡ‚Ρ€ΠΈ Π½Π΅Π³ΠΎ располагаСтся ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ Skeleton, Ρ€Π°Π·ΠΌΠ΅Ρ€Ρ‹ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ ΠΌΡ‹ Π·Π°Π΄Π°Π΅ΠΌ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ пропсов width ΠΈ height.

Рассмотрим этот ΠΌΠΎΠ΄ΡƒΠ»ΡŒ ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½Π΅Π΅: Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Π°Π΅ΠΌ с Π΅Π³ΠΎ ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ скСлСтный экран YouTube.

ΠšΠ°Ρ€ΠΊΠ°ΡΠ½Ρ‹Π΅ экраны Π² стилС YouTube

Установка React

Π‘Π°ΠΌΡ‹ΠΉ простой способ ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ ΠΈ Π½Π°ΡΡ‚Ρ€ΠΎΠΈΡ‚ΡŒ React Π² Π½ΠΎΠ²ΠΎΠΌ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΈ – ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΡƒΡ‚ΠΈΠ»ΠΈΡ‚Ρƒ Create React App. ΠŸΡ€ΠΈ этом Π²Π°ΠΌ ΠΏΠΎΡ‡Ρ‚ΠΈ Π½ΠΈΡ‡Π΅Π³ΠΎ Π½Π΅ придСтся Π΄Π΅Π»Π°Ρ‚ΡŒ – Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π½Π°Π±Ρ€Π°Ρ‚ΡŒ ΠΊΠΎΠΌΠ°Π½Π΄Ρƒ Π² Ρ‚Π΅Ρ€ΠΌΠΈΠ½Π°Π»Π΅. Π‘Π½Π°Ρ‡Π°Π»Π° установитС ΠΌΠΎΠ΄ΡƒΠ»ΡŒ глобально, Ссли Π²Ρ‹ этого Π΅Ρ‰Π΅ Π½Π΅ сдСлали:

npm install -g create-react-app

Π—Π°Ρ‚Π΅ΠΌ создайтС Π½ΠΎΠ²Ρ‹ΠΉ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ skeleton-screens:

npx create-react-app skeleton-screens 

Когда установка Π·Π°Π²Π΅Ρ€ΡˆΠΈΡ‚ΡΡ, ΠΏΠ΅Ρ€Π΅ΠΉΠ΄ΠΈΡ‚Π΅ Π² ΠΏΠ°ΠΏΠΊΡƒ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° ΠΈ запуститС Π»ΠΎΠΊΠ°Π»ΡŒΠ½Ρ‹ΠΉ сСрвСр:

cd skeleton-screens
yarn start

Π’Ρ‹ ΡƒΠ²ΠΈΠ΄ΠΈΡ‚Π΅ привСтствСнный экран React:

Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ интСрфСйса

ВмСсто Ρ€Π΅Π°Π»ΡŒΠ½Ρ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ… с YouTube ΠΌΡ‹ Π±ΡƒΠ΄Π΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π·Π°Ρ€Π°Π½Π΅Π΅ ΠΏΠΎΠ΄Π³ΠΎΡ‚ΠΎΠ²Π»Π΅Π½Π½Ρ‹ΠΉ массив, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π½Π΅ ΡƒΡΠ»ΠΎΠΆΠ½ΡΡ‚ΡŒ руководство Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠΉ Π»ΠΎΠ³ΠΈΠΊΠΎΠΉ.

Π‘ΠΎΠ·Π΄Π°ΠΉΡ‚Π΅ Ρ„Π°ΠΉΠ» data.js Π² ΠΏΠ°ΠΏΠΊΠ΅ src ΠΈ скопируйтС Ρ‚ΡƒΠ΄Π° ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ ΠΊΠΎΠ΄:

const dummyData= [
  {
    section: "Recommended",
    channel: "CNN",
    items: [
      {
        id: "fDObf2AeAP4",
        image: "https://img.youtube.com/vi/fDObf2AeAP4/maxresdefault.jpg",
        title: "75 million Americans ordered to stay home",
        views: "1.9M views",
        published: "3 days agos"
      },
      {
        id: "3AzIgAa0Cm8",
        image: "https://img.youtube.com/vi/3AzIgAa0Cm8/maxresdefault.jpg",
        title: "Gupta: The truth about using chloroquine to fight coronavirus pandemic",
        views: "128K views",
        published: "4 hours ago"
      },
      {
        id: "92B37aXykYw",
        image: "https://img.youtube.com/vi/92B37aXykYw/maxresdefault.jpg",
        title: "Willie Jones STUNS Simon Cowell In Pitch Perfect Performance of 'Your Man'!",
        views: "2.47 million views",
        published: "1 month ago"
      },
      {
        id: "J6rVaFzOEP8",
        image: "https://img.youtube.com/vi/J6rVaFzOEP8/maxresdefault.jpg",
        title: "Guide To Becoming A Self-Taught Software Developer",
        views: "104K views",
        published: "17 days ago"
      },
      {
        id: "Wbk8ZrfU3EM",
        image: "https://img.youtube.com/vi/Wbk8ZrfU3EM/maxresdefault.jpg",
        title: "Tom Hanks and Rita Wilson test positive for coronavirus",
        views: "600k views",
        published: "1 week ago"
      },
      {
        id: "ikHpFgKJax8",
        image: "https://img.youtube.com/vi/ikHpFgKJax8/maxresdefault.jpg",
        title: "Faces Of Africa- The Jerry Rawlings story",
        views: "2.3 million views",
        published: "2014"
      }
    ]
  },
  {
    section: "Breaking News",
    channel: "CGTN America",
    items: [
      {
        id: "tRLDPy1A8pI",
        image: "https://img.youtube.com/vi/tRLDPy1A8pI/maxresdefault.jpg",
        title: "Is Trump blaming China for COVID-19? You decide.",
        views: "876k views",
        published: "9 days ago"
      },
      {
        id: "2ulH1R9hlG8",
        image: "https://img.youtube.com/vi/2ulH1R9hlG8/maxresdefault.jpg",
        title: "Journalist still goes to office during pandemic, see her daily routine",
        views: "873 views",
        published: "3 hours ago"
      },
      {
        id: "\_TkfQ9MaIgU",
        image: "https://img.youtube.com/vi/_TkfQ9MaIgU/maxresdefault.jpg",
        title: "How are small businesses going to survive the economic downturn of the COVID-19 era?",
        views: "283 views",
        published: "4 day ago"
      }
    ]
  }
];
export default dummyData;

Π’ этом Ρ„Ρ€Π°Π³ΠΌΠ΅Π½Ρ‚Π΅ описаны Π΄Π²Π° Π±Π»ΠΎΠΊΠ° страницы – "Π Π΅ΠΊΠΎΠΌΠ΅Π½Π΄ΠΎΠ²Π°Π½Π½ΠΎΠ΅" ΠΈ "ПослСдниС новости" – ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΈΠ· ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… содСрТит нСсколько Π²ΠΈΠ΄Π΅ΠΎ-ΠΏΡ€Π΅Π²ΡŒΡŽ.

Π’Π΅ΠΏΠ΅Ρ€ΡŒ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ эти Π΄Π°Π½Π½Ρ‹Π΅ для вСрстки интСрфСйса. Нам потрСбуСтся Ρ‚Ρ€ΠΈ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π°:

  1. Card – ΠΏΡ€Π΅Π²ΡŒΡŽ Π²ΠΈΠ΄Π΅ΠΎ. Π‘ΠΎΠ΄Π΅Ρ€ΠΆΠΈΡ‚ ΠΌΠΈΠ½ΠΈΠ°Ρ‚ΡŽΡ€Ρƒ Π²ΠΈΠ΄Π΅ΠΎ, Π΅Π³ΠΎ Π½Π°Π·Π²Π°Π½ΠΈΠ΅, количСство просмотров, Π½Π°Π·Π²Π°Π½ΠΈΠ΅ ΠΊΠ°Π½Π°Π»Π° ΠΈ Π΄Π°Ρ‚Ρƒ ΠΏΡƒΠ±Π»ΠΈΠΊΠ°Ρ†ΠΈΠΈ.
  2. CardList – Π³Ρ€ΡƒΠΏΠΏΠ° ΠΏΡ€Π΅Π²ΡŒΡŽ.
  3. App – ΠΊΠΎΡ€Π½Π΅Π²ΠΎΠΉ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ прилоТСния. Он ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ dummyData, ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ каркасный экран Π² Ρ‚Π΅Ρ‡Π΅Π½ΠΈΠ΅ Π΄Π²ΡƒΡ… сСкунд, имитируя Π·Π°Π³Ρ€ΡƒΠ·ΠΊΡƒ Π΄Π°Π½Π½Ρ‹Ρ…, Π° Π·Π°Ρ‚Π΅ΠΌ ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°Π΅Ρ‚ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ CardList.

Π‘ΠΎΠ·Π΄Π°Π΄ΠΈΠΌ ΠΏΠ°ΠΏΠΊΡƒ components Π²Π½ΡƒΡ‚Ρ€ΠΈ src – Π² Π½Π΅ΠΉ Π±ΡƒΠ΄Π΅ΠΌ Ρ€Π°Π·ΠΌΠ΅Ρ‰Π°Ρ‚ΡŒ Ρ„Π°ΠΉΠ»Ρ‹ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ΠΎΠ².

Card

Π‘ΠΎΠ·Π΄Π°ΠΉΡ‚Π΅ Ρ„Π°ΠΉΠ» Card.js Π² ΠΏΠ°ΠΏΠΊΠ΅ components:

Card.js
import React from "react";
const Card = ({ item, channel }) => {
    return (
      <li className="card">
        <a
          href={`https://www.youtube.com/watch?v=${item.id}`}
          target="\_blank"
          rel="noopener noreferrer"
          className="card-link"
        >
          <img src={item.image} alt={item.title} className="card-image" />
          <img src={item.image} alt={item.title} className="channel-image" />
          <h4 className="card-title">{item.title}</h4>
          <p className="card-channel">
            <i>{channel}</i>
          </p>
          <div className="card-metrics">
            {item.views} β€’ {item.published}
          </div>
        </a>
      </li>
    );
  };
export default Card;

ΠŸΡ€ΠΎΡΡ‚ΠΎΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½Ρ‹ΠΉ React-ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π²Ρ‹Π²ΠΎΠ΄ΠΈΡ‚ Π΄Π°Π½Π½Ρ‹Π΅ Π² шаблон.

CardList

Π€Π°ΠΉΠ» components/CardList.js:

CardList.js
import React from "react";
import Card from "./Card";
const CardList = ({ list }) => {
    return (
      <ul className="list">
        {list.items.map((item, index) => {
          return <Card key={index} item={item} channel={list.channel} />;
        })}
      </ul>
    );
  };
export default CardList;

Π­Ρ‚ΠΎΡ‚ ΠΊΠΎΠ΄ Π΅Ρ‰Π΅ ΠΏΡ€ΠΎΡ‰Π΅ – ΠΎΠ½ Π²Ρ‹Π²ΠΎΠ΄ΠΈΡ‚ Π½Π° экран массив ΠΏΡ€Π΅Π²ΡŒΡŽΡˆΠ΅ΠΊ Card.

App

НаконСц, ΠΎΡ‚ΠΊΡ€ΠΎΠΉΡ‚Π΅ Ρ„Π°ΠΉΠ» App.js, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΡƒΠΆΠ΅ создан ΠΏΡ€ΠΈ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° ΠΈ ΠΎΠ±Π½ΠΎΠ²ΠΈΡ‚Π΅ Π² Π½Π΅ΠΌ ΠΊΠΎΠ΄:

App.js
import React, { useState, useEffect } from "react";
import "./App.css";
import dummyData from "./data";
import CardList from "./components/CardList";

const App = () => {
  const [videos, setVideos] = useState([]);
  const [loading, setLoading] = useState(false);

  useEffect(() => {
    setLoading(true);
    const timer = setTimeout(() => {
      setVideos(dummyData);
      setLoading(false);
    }, 2000);
    return () => clearTimeout(timer);
  }, []);
  return (
    <div className="App">
      {
        videos.map((list, index) => {
          return (
            <section key={index}>
              <h2 className="section-title">{list.section}</h2>
              <CardList list={list} />
              <hr />
            </section>
          );
        })}
    </div>
  );
};
export default App;

Π­Ρ‚ΠΎΡ‚ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ слоТнСС, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ ΠΎΠ½ ΠΈΠΌΠ΅Π΅Ρ‚ собствСнноС состояниС.

ΠœΡ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ Ρ…ΡƒΠΊ useState, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Ρ…Ρ€Π°Π½ΠΈΡ‚ΡŒ список Π²ΠΈΠ΄Π΅ΠΎ, Π° Ρ‚Π°ΠΊΠΆΠ΅ состояниС Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ.

Π₯ΡƒΠΊ useEffect ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для ΠΈΠΌΠΈΡ‚Π°Ρ†ΠΈΠΈ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ Π΄Π°Π½Π½Ρ‹Ρ… с сСрвСра с Π·Π°Π΄Π΅Ρ€ΠΆΠΊΠΎΠΉ: старый-Π΄ΠΎΠ±Ρ€Ρ‹ΠΉ setTimeout. Волько вмСсто Ρ€Π΅Π°Π»ΡŒΠ½Ρ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ… ΠΌΡ‹ сохраним Π·Π°Ρ€Π°Π½Π΅Π΅ ΠΏΠΎΠ΄Π³ΠΎΡ‚ΠΎΠ²Π»Π΅Π½Π½Ρ‹ΠΉ массив ΠΈΠ· Ρ„Π°ΠΉΠ»Π° data.js.

ПослС "Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ" Π²Ρ‹Π²ΠΎΠ΄ΠΈΠΌ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ Π±Π»ΠΎΠΊ Π²ΠΈΠ΄Π΅ΠΎ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΌΠ΅Ρ‚ΠΎΠ΄Π° videos.map. Массив ΠΊΠ°Ρ€Ρ‚ΠΎΡ‡Π΅ΠΊ пСрСдаСтся Π² Π°Ρ‚Ρ€ΠΈΠ±ΡƒΡ‚Π΅ list ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρƒ CardList, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΎΡ‚Π²Π΅Ρ‡Π°Π΅Ρ‚ Π·Π° Π΅Π³ΠΎ Π²ΠΈΠ·ΡƒΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ.

Пока Π² шаблонС Π½Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ пСрСмСнная loading,скоро ΠΌΡ‹ ΠΊ Π½Π΅ΠΉ вСрнСмся.

Бтилизация

Π”ΠΎ сих ΠΏΠΎΡ€ ΠΌΡ‹ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ расставляли классы Π² вСрсткС, Π½ΠΎ Π½Π΅ добавляли Ρ€Π΅Π°Π»ΡŒΠ½Ρ‹Π΅ стили для Π½ΠΈΡ…. ΠŸΠΎΡ€Π° ΠΎΠ±Π»Π°Π³ΠΎΡ€ΠΎΠ΄ΠΈΡ‚ΡŒ внСшний Π²ΠΈΠ΄ прилоТСния. ΠžΡ‚ΠΊΡ€ΠΎΠΉΡ‚Π΅ Ρ„Π°ΠΉΠ» App.css Π² ΠΏΠ°ΠΏΠΊΠ΅ src ΠΈ Π·Π°ΠΌΠ΅Π½ΠΈΡ‚Π΅ ΠΊΠΎΠ΄ Π½Π° ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ:

.App {
  max-width: 960px;
  margin: 0 auto;
  font-size: 16px;
}
.list {
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  list-style: none;
  padding: 0;
}
.section-title {
  margin-top: 30px;
}
.card {
  width: calc(33% - 10px);
  margin: 20px 0;
}
.card-link {
  color: inherit;
  text-decoration: none;
}
.card-image {
  width: 100%;
}
.channel-image {
  border-radius: 100%;
  padding: 0, 10px, 0, 0;
  width: 40px;
  height: 40px;  
}
.card-title {
  margin-top: 10px;
  margin-bottom: 0;
}
.card-channel {
  margin-top: 5px;
  margin-bottom: 5px;
  font-size: 14px;
}
/* Tablets */
@media (max-width: 1000px) {
  .App {
    max-width: 600px;
  }
  .card {
    width: calc(50% - 22px);
  }
}
/* Mobiles */
@media (max-width: 640px) {
  .App {
    max-width: 100%;
    padding: 0 15px;
  }
  .card {
    width: 100%;
  }
}

Π’Π΅ΠΏΠ΅Ρ€ΡŒ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ ΠΊΠ°ΠΊ выглядит интСрфСйс, ΠΏΠΎΠΊΠ° Π±Π΅Π· каркасных экранов. ΠŸΠ°Ρ€Ρƒ сСкунд, ΠΊΠΎΠ³Π΄Π° страница загруТаСтся, ΠΌΡ‹ Π²ΠΈΠ΄ΠΈΠΌ Π±Π΅Π»Ρ‹ΠΉ экран, Π° Π·Π°Ρ‚Π΅ΠΌ всС Π΄Π°Π½Π½Ρ‹Π΅ ΠΏΠΎΡΠ²Π»ΡΡŽΡ‚ΡΡ сразу.

Π˜Π½Ρ‚Π΅Ρ€Ρ„Π΅ΠΉΡ ΠΊΠ»ΠΎΠ½Π° YouTube Π±Π΅Π· каркасных экранов

ΠŸΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ React Loading Skeleton

Π’ React Loading Skeleton Π²Π°ΠΌ Π½Π΅ Π½ΡƒΠΆΠ½ΠΎ пошагово ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ скСлСтный экран, Ρ‚Ρ‰Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ подбирая ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ Ρ‚ΠΈΠΏΠΎΠ³Ρ€Π°Ρ„ΠΈΠΊΠΈ, отступы ΠΈ ΠΏΡ€ΠΎΡ‡ΠΈΠ΅ стили ΠΏΠΎΠ΄ ваш ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚. Π•Π³ΠΎ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΠΌΠ΅ΡΡ‚ΠΈΡ‚ΡŒ прямо Π²Π½ΡƒΡ‚Ρ€ΡŒ вашСго ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π° вмСсто Π·Π°Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌΠΎΠ³ΠΎ ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚Π°.

Π£ этой Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ Π΅ΡΡ‚ΡŒ ΠΏΠ°Ρ€Π° ΠΏΠΎΠ»Π΅Π·Π½Ρ‹Ρ… плюшСк: лСгкая тСмизация ΠΈ ΡƒΠΊΠ°Π·Π°Π½ΠΈΠ΅ ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ Ρ†ΠΈΠΊΠ»Π° Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΈ.

Π’Π΅ΠΌΡ‹

React Loading Skeleton ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ ΠΏΡ€ΠΎΡΡ‚ΡƒΡŽ настройку Ρ‚Π΅ΠΌ. Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π»Π΅Π³ΠΊΠΎ ΠΏΠΎΠΌΠ΅Π½ΡΡ‚ΡŒ ΡΡ‚ΠΈΠ»ΡŒ сразу всСх скСлСтных экранов, внСся измСнСния Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π² ΠΎΠ΄Π½ΠΎΠΌ мСстС. Π—Π° это ΠΎΡ‚Π²Π΅Ρ‡Π°Π΅Ρ‚ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ SkeletonTheme.

import Skeleton, { SkeletonTheme } from "react-loading-skeleton";

<SkeletonTheme color="grey" highlightColor="#444">
  <p>
    <Skeleton height={250} width={300} count={1} />
  </p>
</SkeletonTheme>

<SkeletonTheme color="#990" highlightColor="#550">
  <p>
    <Skeleton height={250} width={300} count={1} />
  </p>
</SkeletonTheme>
ΠŸΡ€ΠΎΡΡ‚Π°Ρ настройка Ρ‚Π΅ΠΌΡ‹ для каркасных экранов

ΠŸΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ

Помимо ΠΎΡ‡Π΅Π²ΠΈΠ΄Π½Ρ‹Ρ… пропсов height, width ΠΈ color, ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ Ρ‚Π°ΠΊΠΆΠ΅ ΡƒΠΊΠ°Π·Π°Ρ‚ΡŒ свойство duration.

<Skeleton duration={2} />

По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ ΠΎΠ½ΠΎ Ρ€Π°Π²Π½ΠΎ 1.2. Π­Ρ‚ΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ опрСдСляСт ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ ΠΎΠ΄Π½ΠΎΠ³ΠΎ Ρ†ΠΈΠΊΠ»Π° Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΈ экрана.

Π‘ΠΎΠ»ΡŒΡˆΠ΅ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΈ ΠΎ настройках ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π° Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π½Π°ΠΉΡ‚ΠΈ Π² Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΠΈ.

Установка ΠΏΠ°ΠΊΠ΅Ρ‚Π°

Π§Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΡƒ react-loading-skeleton Π² ΠΏΡ€ΠΎΠ΅ΠΊΡ‚, запуститС ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΡƒΡŽ ΠΊΠΎΠΌΠ°Π½Π΄Ρƒ:

npm install react-loading-skeleton

Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π°

Π’Π΅ΠΏΠ΅Ρ€ΡŒ ΠΌΠΎΠΆΠ½ΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ каркасныС экраны для Π²ΠΈΠ΄Π΅ΠΎ-Π΄Π°Π½Π½Ρ‹Ρ…. Π’ ΠΏΠ°ΠΏΠΊΠ΅ components создайтС Π½ΠΎΠ²Ρ‹ΠΉ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ SkeletonCard.js:

SkeletonCard.js
import React from "react";
import Skeleton from "react-loading-skeleton";
const SkeletonCard = () => {
    return (
      <section>
        <h2 className="section-title">
          <Skeleton height={30} width={300} />
        </h2>

        <ul className="list">
          {Array(9)
            .fill()
            .map((item, index) => (
              <li className="card" key={index}>
                <Skeleton height={180} />
                <h4 className="card-title">
                  <Skeleton circle={true} height={50} width={50} />  
                  <Skeleton height={36} width={`80%`} />
                </h4>
                <p className="card-channel">
                  <Skeleton width={`60%`} />
                </p>
                <div className="card-metrics">
                  <Skeleton width={`90%`} />
                </div>
              </li>
            ))}
        </ul>
      </section>
    );
  };
  export default SkeletonCard;

Π—Π΄Π΅ΡΡŒ ΠΌΡ‹ создаСм нСупорядочСнный список ΠΈ заполняСм Π΅Π³ΠΎ элСмСнтами (li) с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΌΠ΅Ρ‚ΠΎΠ΄Π° Array.fill(). ВсСго элСмСнтов 9: ΠΏΠΎ количСству Π²ΠΈΠ΄Π΅ΠΎΡ€ΠΎΠ»ΠΈΠΊΠΎΠ² Π² массивС dummyData, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π±ΡƒΠ΄ΡƒΡ‚ Π²Ρ‹Π²Π΅Π΄Π΅Π½Ρ‹ Π½Π° страницу послС Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ.

Π§Ρ‚ΠΎΠ±Ρ‹ Π²ΡΠΏΠΎΠΌΠ½ΠΈΡ‚ΡŒ, ΠΊΠ°ΠΊ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ ΠΌΠ΅Ρ‚ΠΎΠ΄ Array.fill, заглянитС Π² Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚Π°Ρ†ΠΈΡŽ Π½Π° MDN. Нам сСйчас Π²Π°ΠΆΠ½ΠΎ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ, Ρ‡Ρ‚ΠΎ ΠΎΠ½ создаСт массив с 9 элСмСнтами, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΠΏΡ€ΠΎΠΈΡ‚Π΅Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΈ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΌΠ΅Ρ‚ΠΎΠ΄Π° Array.map ΠΏΡ€Π΅Π²Ρ€Π°Ρ‚ΠΈΡ‚ΡŒ Π² массив элСмСнтов li.

Π˜Ρ‚Π°ΠΊ, для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ Ρ„Π΅ΠΉΠΊΠΎΠ²ΠΎΠ³ΠΎ Π²ΠΈΠ΄Π΅ΠΎ Ρƒ нас ΡƒΠΆΠ΅ Π΅ΡΡ‚ΡŒ каркас, состоящий ΠΈΠ· Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… Π±Π»ΠΎΠΊΠΎΠ². ΠŸΡ€ΠΎΠΏΡΡ‹ height ΠΈ width ΠΎΡ‚Π²Π΅Ρ‡Π°ΡŽΡ‚ Π·Π° Ρ€Π°Π·ΠΌΠ΅Ρ€Ρ‹ Π±Π»ΠΎΠΊΠ°, Π° circle={true} Ρ„ΠΎΡ€ΠΌΠΈΡ€ΡƒΠ΅Ρ‚ ΠΊΡ€ΡƒΠ³Π»Ρ‹ΠΉ Π±Π»ΠΎΠΊ.

По ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ для ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π° React Loading Skeleton ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½Π° симпатичная ΠΏΡƒΠ»ΡŒΡΠΈΡ€ΡƒΡŽΡ‰Π°Ρ анимация. ΠŸΡ€ΠΈ ΠΆΠ΅Π»Π°Π½ΠΈΠΈ Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ свою Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΡŽ, ΠΌΡ‹ ΠΆΠ΅ Π²ΠΎΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡΡ Π΄Π΅Ρ„ΠΎΠ»Ρ‚Π½ΠΎΠΉ.

ΠžΡΡ‚Π°Π»ΠΎΡΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ каркасный экран Π² ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΈ ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°Ρ‚ΡŒ Π΅Π³ΠΎ, ΠΏΠΎΠΊΠ° происходит ΠΏΠΎΠ΄Π³Ρ€ΡƒΠ·ΠΊΠ° Π΄Π°Π½Π½Ρ‹Ρ…. ВнСситС измСнСния Π² ΠΊΠΎΠ΄ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π° App:

App.js
import SkeletonCard from './components/SkeletonCard';

const App = () => {
  // ...

  return (
    <div className="App">
      {loading && <SkeletonCard />}
      {!loading &&
        videos.map((list, index) => {
          return (
            <section key={index}>
              <h2 className="section-title">{list.section}</h2>
              <CardList list={list} />
              <hr />
            </section>
          );
        })}
    </div>
  );
};

Π’Π΅ΡΡŒ исходный ΠΊΠΎΠ΄ Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π½Π°ΠΉΡ‚ΠΈ Π² Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚ΠΎΡ€ΠΈΠΈ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°.

НашС ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΏΠΎΠ»Π½ΠΎΡΡ‚ΡŒΡŽ Π³ΠΎΡ‚ΠΎΠ²ΠΎ. ΠŸΡ€ΠΈ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΈΠΈ отобраТаСтся красивый каркасный экран с ΠΏΡƒΠ»ΡŒΡΠΈΡ€ΡƒΡŽΡ‰Π΅ΠΉ Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠ΅ΠΉ, Π° Π² это врСмя Π·Π° ΠΊΠ°Π΄Ρ€ΠΎΠΌ ΠΏΠΎΠ΄Π³Ρ€ΡƒΠΆΠ°ΡŽΡ‚ΡΡ Π΄Π°Π½Π½Ρ‹Π΅. Как Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΌΡ‹ ΠΈΡ… ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠΌ (Π½Π° Π΄Π΅ΠΌΠΎ-ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ стоит Π·Π°Π΄Π΅Ρ€ΠΆΠΊΠ° Π² 5 сСкунд), Ρ‚ΠΎ сразу Π²Ρ‹Π²Π΅Π΄Π΅ΠΌ Π½Π° страницу.

Π’ΠΎΡ‚ Ρ‚Π°ΠΊ выглядит Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚:

Π—Π°ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅

ΠšΠ°Ρ€ΠΊΠ°ΡΠ½Ρ‹Π΅ ΠΈΠ»ΠΈ скСлСтныС экраны Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΡƒΠ»ΡƒΡ‡ΡˆΠ°ΡŽΡ‚ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΠΉ ΠΎΠΏΡ‹Ρ‚. Они ΠΈΠ·Π±Π°Π²Π»ΡΡŽΡ‚ посСтитСлСй сайта ΠΎΡ‚ растСрянности ΠΈ нСпонимания происходящСго, Π° Ρ‚Π°ΠΊΠΆΠ΅ ΡΠΎΠ·Π΄Π°ΡŽΡ‚ Π²ΠΏΠ΅Ρ‡Π°Ρ‚Π»Π΅Π½ΠΈΠ΅, Π±ΡƒΠ΄Ρ‚ΠΎ ΠΊΠΎΠ½Ρ‚Π΅Π½Ρ‚ ΡƒΠΆΠ΅ Π½Π° ΠΏΠΎΠ΄Ρ…ΠΎΠ΄Π΅ ΠΈ Π²ΠΎΡ‚-Π²ΠΎΡ‚ Π΅Π³ΠΎ ΠΏΠΎΠΊΠ°ΠΆΡƒΡ‚.

Для создания ΠΏΠΎΠ΄ΠΎΠ±Π½ΠΎΠ³ΠΎ интСрфСйса ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π³ΠΎΡ‚ΠΎΠ²Ρ‹Π΅ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ ΠΈΠ»ΠΈ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π΅Π³ΠΎ ΡΠ°ΠΌΠΎΡΡ‚ΠΎΡΡ‚Π΅Π»ΡŒΠ½ΠΎ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ простых гСомСтричСских Ρ„ΠΈΠ³ΡƒΡ€ ΠΈ ΠΊΠ°ΠΏΠ»ΠΈ Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΈ.

Π˜ΡΡ‚ΠΎΡ‡Π½ΠΈΠΊΠΈ

Π›Π£Π§Π¨Π˜Π• БВАВЬИ ПО Π’Π•ΠœΠ•