Напісанне разметкі з JSX

JSX — гэта пашырэнне сінтаксісу для JavaScript, якое дазваляе вам пісаць падобную на HTML разметку ўнутры JavaScript файла. Хай ёсць і іншыя спосабы напісання кампанентаў, большасць React распрацоўшчыкаў аддаюць перавагу лаканічнасці JSX, і большасць кодавых баз выкарыстоўваюць яго.

You will learn

  • Чаму React сумяшчае разметку з логікай рэндэру
  • Чым JSX адрозніваецца ад HTML
  • Як паказваць інфармацыю з дапамогай JSX

JSX: дадаванне разметкі ў JavaScript

Вэб пабудаваны на HTML, CSS і JavaScript. На працягу многіх гадоў вэб-распрацоўшчыкі захоўвалі змесціва ў HTML, дызайн у CSS, а логіку ў JavaScript. Найчасцей у розных файлах! Змесціва знаходзілася ўнутры HTML разметкі, у той час, пакуль логіка змяшчалася асобна ў JavaScript:

HTML разметка на фіялетавым фоне, дзе div змяшчае два дачынных элементы: p і form.
HTML разметка на фіялетавым фоне, дзе div змяшчае два дачынных элементы: p і form.

HTML

Тры JavaScript апрацоўшчыкі на жоўтым фоне: onSubmit, onLogin і onClick.
Тры JavaScript апрацоўшчыкі на жоўтым фоне: onSubmit, onLogin і onClick.

JavaScript

Але з павелічэннем інтэрактыўнасці ў Вэб, колькасць логікі стала перавышаць колькасць кантэнту. JavaScript кіраваў HTML! Таму ў React логіка рэндэру і разметка жывуць разам у адным месцы — у кампанентах

Кампанент React з HTML і JavaScript з папярэдняга прыкладу злучанымі разам. Функцыя Sidebar выклікае функцыю isLoggedIn, яны вылучаныя жоўтым. Унутры змяшчаюцца элементы p і Form, што паказаны на наступным відарысе, яны вылучаны фіялетавым.
Кампанент React з HTML і JavaScript з папярэдняга прыкладу злучанымі разам. Функцыя Sidebar выклікае функцыю isLoggedIn, яны вылучаныя жоўтым. Унутры змяшчаюцца элементы p і Form, што паказаны на наступным відарысе, яны вылучаны фіялетавым.

React кампанент Sidebar.js

Кампанент React з HTML і JavaScript з папярэдняга прыкладу злучанымі разам. Функцыя Form змяшчае два апрацоўшчыкі onClick і onSubmit, яны вылучаныя жоўтым. За імі HTML вылучаны фіялетавым. HTML змяшчае элемент form і два элементы input унутры, кожны з якіх мае пропс onClick.
Кампанент React з HTML і JavaScript з папярэдняга прыкладу злучанымі разам. Функцыя Form змяшчае два апрацоўшчыкі onClick і onSubmit, яны вылучаныя жоўтым. За імі HTML вылучаны фіялетавым. HTML змяшчае элемент form і два элементы input унутры, кожны з якіх мае пропс onClick.

React кампанент Form.js

Захоўванне логікі рэндэру кнопкі разам з разметкай гарантуе, што яны застануцца сінхранізаванымі пасля змен. І наадварот, дэталі, якія не маюць дачынення адныя да іншых, такія, як разметка кнопкі і разметка бакавой панэлі, ізаляваныя, што дазваляе больш бяспечна змяняць іх незалежна адно ад аднаго.

Кожны кампанент React — функцыя JavaScript, якая можа змяшчаць разметку, якую React будзе рэндэрыць у браўзеры. Кампаненты React выкарыстоўваюць пашырэнне сінтаксісу, якое называецца JSX каб апісваць разметку. Разметка JSX вельмі падобная да HTML, але яна больш строгая і можа паказваць даныя дынамічна. Найлепшы спосаб зразумець гэта — паспрабаваць перарабіць HTML разметку ў JSX разметку.

Note

JSX і React — дзве асобныя рэчы. Яны часта выкарыстоўваюцца разам, але вы можаце выкарыстоўваць іх незалежна адно ад іншага. JSX — пашырэнне сінтаксісу, React жа — JavaScript бібліятэка.

Ператварэнне HTML у JSX

Уявім, што ў вас ёсць (цалкам правільны) HTML:

<h1>Спіс задач Хедзі Ламар</h1>
<img
src="https://i.imgur.com/yXOvdOSs.jpg"
alt="Hedy Lamarr"
class="photo"
>
<ul>
<li>Вынайсці новыя святлафоры
<li>Адрэпетаваць сцэну з фільма
<li>Палепшыць тэхналогію спектра
</ul>

І вы хочаце выкарыстоўваць яго ў сваім кампаненце:

export default function TodoList() {
return (
// ???
)
}

Калі вы яго проста скапіюеце і ўставіце, ён не спрацуе:

export default function TodoList() {
  return (
    // Гэта не будзе працаваць!
    <h1>Спіс задач Хедзі Ламар</h1>
    <img 
      src="https://i.imgur.com/yXOvdOSs.jpg" 
      alt="Hedy Lamarr" 
      class="photo"
    >
    <ul>
      <li>Вынайсці новыя святлафоры
      <li>Адрэпетаваць сцэну з фільма
      <li>Палепшыць тэхналогію спектра
    </ul>

Гэта адбываецца таму што JSX стражэйшы за HTML і мае шэраг дадатковых правіл! Калі вы паспрабуеце чытаць паведамленні пра памылкі вышэй, яны дапамогуць вам выправіць разметку, таксама вы можаце скарыстацца дапаможнікам ніжэй.

Note

У большасці выпадкаў React будзе паказваць вам карысныя паведамленні пра памылкі прама на экране. Калі вы захраслі, паспрабуйце з імі азнаёміцца!

Правілы JSX

1. Заўсёды вяртайце адзін каранёвы элемент

Каб вярнуць некалькі элементаў у межах аднаго кампанента, абгарніце іх у адзін агульны тэг.

Напрыклад, вы можаце выкарыстоўваць <div>:

<div>
<h1>Спіс задач Хедзі Ламар</h1>
<img
src="https://i.imgur.com/yXOvdOSs.jpg"
alt="Hedy Lamarr"
class="photo"
>
<ul>
...
</ul>
</div>

Калі вы не хочаце дадаваць яшчэ адзін <div> у сваю разметку, вы можаце выкарыстоўваць пару тэгаў <> і </> замест:

<>
<h1>Спіс задач Хедзі Ламар</h1>
<img
src="https://i.imgur.com/yXOvdOSs.jpg"
alt="Hedy Lamarr"
class="photo"
>
<ul>
...
</ul>
</>

Гэты пусты тэг называецца Фрагмент. Фрагменты дазваляюць вам групаваць рэчы, не пакідаючы слядоў у HTML дрэвы ў браўзеры.

Deep Dive

Чаму некалькі JSX тэгаў павінны быць абгорнутыя ў адзін?

JSX выглядае як HTML, але «пад капотам» трансфармуецца ў звычайныя JavaScript аб’екты. Як вы не можаце вярнуць з функцыі два аб’екты, не абгарнуўшы іх у масіў, такім жа чынам нельга вярнуць два JSX тэгі, не абгарнуўшы іх у іншы тэг ці Фрагмент.

2. Закрывайце ўсе свае тэгі

JSX патрабуе, каб усе тэгі былі закрытыя: няпарныя тэгі, такія як <img>, ператвараюцца ў <img />, і абгортачныя тэгі, такія як <li>апельсіны, павінны быць абавязкова закрытымі: <li>апельсіны</li>.

Тэгі фота Хедзі Ламар і элементаў спіса павінны закрывацца вось такім чынам:

<>
<img
src="https://i.imgur.com/yXOvdOSs.jpg"
alt="Hedy Lamarr"
class="photo"
/>
<ul>
<li>Вынайсці новыя святлафоры</li>
<li>Адрэпетаваць сцэну з фільма</li>
<li>Палепшыць тэхналогію спектра</li>
</ul>
</>

3. camelCase для ўсяго амаль ўсяго!

JSX ператвараецца ў JavaScript і атрыбуты, напісаныя ў JSX, ператвараюцца ў ключы JavaScript аб’ектаў. Ва ўласных кампанентах у вас часта можа ўзнікаць патрэбнасць у чытанні гэтых атрыбутаў з пераменных. Але JavaScript мае абмежаванні ў назвах пераменных. Напрыклад, назвы не могуць уключаць злучнікі ці зарэзерваваныя словы, такія як class.

Таму ў React шмат якія HTML і SVG атрыбуты напісаныя ў camelCase. Напрыклад, замест stroke-width трэба выкарыстоўваць strokeWidth. Так як class — зарэзерваванае слова, у React трэба пісаць className замест яго, што суадносіцца з адпаведнай уласцівасцю DOM:

<img
src="https://i.imgur.com/yXOvdOSs.jpg"
alt="Hedy Lamarr"
className="photo"
/>

Вы можаце знайсці ўсе гэтыя атрыбуты ў спісе пропсаў DOM кампанентаў. Калі вы штосьці напісалі не так, не хвалюйцеся, React паведаміць вам пра гэта і прапануе магчыма правільны варыянт у кансолі вашага браўзера.

Pitfall

Так гістарычна склалася, што атрыбуты aria-* і data-* напісаныя праз злучнікі, як і ў HTML.

Падказка: карыстайцеся JSX канвертарам

Перапісваць усе гэтыя атрыбуты ва ўжо існуючай разметцы можа быць стомным! Мы раім карыстацца канвертарам каб перакласці вашыя існуючыя HTML і SVG у JSX. Канвертары вельмі карысныя на практыцы, але ўсё яшчэ варта разумець, што адбываецца, каб пісаць JSX было камфортна.

Вось так мае выглядаць канчатковы вынік:

export default function TodoList() {
  return (
    <>
      <h1>Спіс задач Хедзі Ламар</h1>
      <img 
        src="https://i.imgur.com/yXOvdOSs.jpg" 
        alt="Hedy Lamarr" 
        className="photo" 
      />
      <ul>
        <li>Вынайсці новыя святлафоры</li>
        <li>Адрэпетаваць сцэну з фільма</li>
        <li>Палепшыць тэхналогію спектра</li>
      </ul>
    </>
  );
}

Recap

Цяпер вы ведаеце чаму JSX існуе і як выкарыстоўваць яго ў кампанентах:

  • Кампаненты React групуюць логіку рэндэру разам з разметкай таму што яны звязаныя паміж сабой.
  • JSX падобны да HTML, але мае адрозненні. Вы можаце выкарыстоўваць канвертар, калі тое патрэбна.
  • Паведамленні пра памылкі часта будуць падказваць вам кірунак хутчэйшага вырашэння праблемы.

Challenge 1 of 1:
Ператварыце HTML у JSX

Дадзены HTML быў устаўлены ў кампанент, але ён не з’яўляецца правільным JSX. Выправіце гэта:

export default function Bio() {
  return (
    <div class="intro">
      <h1>Вітаю на сваім вэб-сайце!</h1>
    </div>
    <p class="summary">
      Тут вы можаце азнаёміцца з маімі думкамі.
      <br><br>
      <b>Таксама тут ёсць <i>фотаздымкі</b></i> навукоўцаў!
    </p>
  );
}

Карыстацца канвертарам ці зрабіць самастойна — ваш асабісты выбар!