JavaScript у JSX з фігурними дужками

JSX дозволяє писати HTML-подібну розмітку всередині JavaScript-файлу, зберігаючи логіку рендерингу та вміст в одному місці. Іноді вам може знадобитися додати трохи JavaScript-логіки або послатися на динамічну властивість всередині цієї розмітки. У цій ситуації ви можете використовувати фігурні дужки у вашому JSX, щоб відкрити вікно для JavaScript.

  • Як передавати рядки у лапках
  • Як посилатися на змінну JavaScript всередині JSX за допомогою фігурних дужок
  • Як викликати функцію JavaScript всередині JSX за допомогою фігурних дужок
  • Як використовувати об'єкт JavaScript всередині JSX з фігурними дужками

Передача рядків у лапках

Коли ви хочете передати JSX рядковий атрибут, ви берете його в одинарні або подвійні лапки:

export default function Avatar() {
  return (
    <img
      className="avatar"
      src="https://i.imgur.com/7vQD0fPs.jpg"
      alt="Gregorio Y. Zara"
    />
  );
}
.avatar { border-radius: 50%; height: 90px; }

Тут "https://i.imgur.com/7vQD0fPs.jpg" та "Gregorio Y. Zara" передаються як рядки.

А якщо вам потрібно динамічно вказати текст src або alt? Ви можете використовувати значення з JavaScript, замінивши " і " на { і }:

export default function Avatar() {
  const avatar = 'https://i.imgur.com/7vQD0fPs.jpg';
  const description = 'Gregorio Y. Zara';
  return (
    <img
      className="avatar"
      src={avatar}
      alt={description}
    />
  );
}
.avatar { border-radius: 50%; height: 90px; }

Помітьте різницю між className="avatar", який вказує ім'я класу CSS "avatar", що робить зображення круглим, і src={avatar}, який зчитує значення змінної JavaScript з назвою avatar. Це тому, що фігурні дужки дозволяють працювати з JavaScript прямо у вашій розмітці!

За допомогою фігурних дужок: Вікно у світ JavaScript

JSX - це спеціальний спосіб написання JavaScript. Це означає, що всередині нього можна використовувати JavaScript - за допомогою фігурних дужок { }. У наведеному нижче прикладі спочатку оголошується ім'я вченого, name, а потім вставляється фігурними дужками всередину <h1>:

export default function TodoList() {
  const name = 'Gregorio Y. Zara';
  return (
    <h1>{name}'s To Do List</h1>
  );
}

Спробуйте змінити значення name з 'Gregorio Y. Zara' на 'Hedy Lamarr'. Подивіться, як змінився заголовок списку?

Будь-який вираз JavaScript буде працювати між фігурними дужками, включно з викликами функцій на зразок formatDate():

const today = new Date();

function formatDate(date) {
  return new Intl.DateTimeFormat(
    'en-US',
    { weekday: 'long' }
  ).format(date);
}

export default function TodoList() {
  return (
    <h1>To Do List for {formatDate(today)}</h1>
  );
}

Де використовувати фігурні дужки

Всередині JSX можна використовувати фігурні дужки лише двома способами:

  1. Як текст безпосередньо всередині тегу JSX: <h1>{name}'s To Do List</h1> працює, але <{tag}>Gregorio Y. Zara's To Do List</{tag}> не буде.
  2. Як атрибути безпосередньо після знаку =: src={avatar} прочитає змінну avatar, а src="{avatar}" передасть рядок "{avatar}".

Використання "подвійних завитків": CSS та інші об'єкти в JSX

.

Крім рядків, чисел та інших виразів JavaScript, у JSX можна передавати навіть об'єкти. Об'єкти також позначаються фігурними дужками, наприклад, { name: "Hedy Lamarr", inventions: 5 }. Тому, щоб передати JS-об'єкт в JSX, ви повинні обгорнути об'єкт в ще одну пару фігурних дужок: person={{ name: "Hedy Lamarr", inventions: 5 }}.

Ви можете побачити це у вбудованих стилях CSS в JSX. React не вимагає від вас використання вбудованих стилів (CSS класи чудово працюють у більшості випадків). Але коли вам потрібний вбудований стиль, ви передаєте об'єкт в атрибут style:

export default function TodoList() {
  return (
    <ul style={{
      backgroundColor: 'black',
      color: 'pink'
    }}>
      <li>Improve the videophone</li>
      <li>Prepare aeronautics lectures</li>
      <li>Work on the alcohol-fuelled engine</li>
    </ul>
  );
}
body { padding: 0; margin: 0 }
ul { padding: 20px 20px 20px 40px; margin: 0; }

Спробуйте змінити значення параметрів backgroundColor та color.

Ви дійсно можете побачити об'єкт JavaScript всередині фігурних дужок, якщо напишете його ось так:

<ul style={
  {
    backgroundColor: 'black',
    color: 'pink'
  }
}>

Наступного разу, коли ви побачите {{ та }} у JSX, знайте, що це не що інше, як об'єкт всередині JSX-обгорток!

Вбудовані властивості style записуються у camelCase. Наприклад, HTML <ul style="background-color: black"> буде записано як <ul style={{ backgroundColor: 'black' }}> у вашому компоненті.

Більше задоволення від об'єктів JavaScript та фігурних дужок

Ви можете перемістити кілька виразів в один об'єкт і посилатися на них у вашому JSX всередині фігурних дужок:

const person = {
  name: 'Gregorio Y. Zara',
  theme: {
    backgroundColor: 'black',
    color: 'pink'
  }
};

export default function TodoList() {
  return (
    <div style={person.theme}>
      <h1>{person.name}'s Todos</h1>
      <img
        className="avatar"
        src="https://i.imgur.com/7vQD0fPs.jpg"
        alt="Gregorio Y. Zara"
      />
      <ul>
        <li>Improve the videophone</li>
        <li>Prepare aeronautics lectures</li>
        <li>Work on the alcohol-fuelled engine</li>
      </ul>
    </div>
  );
}
body { padding: 0; margin: 0 }
body > div > div { padding: 20px; }
.avatar { border-radius: 50%; height: 90px; }

У цьому прикладі об'єкт JavaScript person містить рядок name та об'єкт theme:

const person = {
  name: 'Gregorio Y. Zara',
  theme: {
    backgroundColor: 'black',
    color: 'pink'
  }
};

Компонент може використовувати ці значення з person таким чином:

<div style={person.theme}>
  <h1>{person.name}'s Todos</h1>

JSX є дуже мінімальною мовою шаблонів, оскільки вона дозволяє організовувати дані та логіку за допомогою JavaScript.

Тепер ви знаєте про JSX майже все:

  • Атрибути JSX всередині лапок передаються як рядки.
  • Фігурні дужки дозволяють додавати до розмітки логіку JavaScript та змінні
  • .
  • Вони працюють всередині вмісту тегу JSX або одразу після = в атрибутах.
  • {{ та }} не є спеціальним синтаксисом: це об'єкт JavaScript, захований у фігурні дужки JSX.

виправити помилку

Цей код завершується аварійно з помилкою, яка говорить Objects are not valid as a React child:

const person = {
  name: 'Gregorio Y. Zara',
  theme: {
    backgroundColor: 'black',
    color: 'pink'
  }
};

export default function TodoList() {
  return (
    <div style={person.theme}>
      <h1>{person}'s Todos</h1>
      <img
        className="avatar"
        src="https://i.imgur.com/7vQD0fPs.jpg"
        alt="Gregorio Y. Zara"
      />
      <ul>
        <li>Improve the videophone</li>
        <li>Prepare aeronautics lectures</li>
        <li>Work on the alcohol-fuelled engine</li>
      </ul>
    </div>
  );
}
body { padding: 0; margin: 0 }
body > div > div { padding: 20px; }
.avatar { border-radius: 50%; height: 90px; }

Чи можете ви знайти проблему?

Подивіться, що знаходиться всередині фігурних дужок. Чи правильно ми вводимо туди дані?

Це відбувається тому, що у цьому прикладі у розмітку рендериться сам об'єкт , а не рядок: <h1>{person}'s Todos</h1> намагається відрендерити весь об'єкт person! Включення необроблених об'єктів як текстового вмісту спричиняє помилку, оскільки React не знає, як ви хочете їх відобразити.

Щоб виправити, замініть <h1>{person}'s Todos</h1> на <h1>{person.name}'s Todos</h1>:

const person = {
  name: 'Gregorio Y. Zara',
  theme: {
    backgroundColor: 'black',
    color: 'pink'
  }
};

export default function TodoList() {
  return (
    <div style={person.theme}>
      <h1>{person.name}'s Todos</h1>
      <img
        className="avatar"
        src="https://i.imgur.com/7vQD0fPs.jpg"
        alt="Gregorio Y. Zara"
      />
      <ul>
        <li>Improve the videophone</li>
        <li>Prepare aeronautics lectures</li>
        <li>Work on the alcohol-fuelled engine</li>
      </ul>
    </div>
  );
}
body { padding: 0; margin: 0 }
body > div > div { padding: 20px; }
.avatar { border-radius: 50%; height: 90px; }

Витяг інформації в об'єкт

Витягнути URL-адресу зображення до об'єкта person.

const person = {
  name: 'Gregorio Y. Zara',
  theme: {
    backgroundColor: 'black',
    color: 'pink'
  }
};

export default function TodoList() {
  return (
    <div style={person.theme}>
      <h1>{person.name}'s Todos</h1>
      <img
        className="avatar"
        src="https://i.imgur.com/7vQD0fPs.jpg"
        alt="Gregorio Y. Zara"
      />
      <ul>
        <li>Improve the videophone</li>
        <li>Prepare aeronautics lectures</li>
        <li>Work on the alcohol-fuelled engine</li>
      </ul>
    </div>
  );
}
body { padding: 0; margin: 0 }
body > div > div { padding: 20px; }
.avatar { border-radius: 50%; height: 90px; }

Перемістіть URL-адресу зображення у властивість person.imageUrl і прочитайте її з тегу <img> за допомогою curlies:

const person = {
  name: 'Gregorio Y. Zara',
  imageUrl: "https://i.imgur.com/7vQD0fPs.jpg",
  theme: {
    backgroundColor: 'black',
    color: 'pink'
  }
};

export default function TodoList() {
  return (
    <div style={person.theme}>
      <h1>{person.name}'s Todos</h1>
      <img
        className="avatar"
        src={person.imageUrl}
        alt="Gregorio Y. Zara"
      />
      <ul>
        <li>Improve the videophone</li>
        <li>Prepare aeronautics lectures</li>
        <li>Work on the alcohol-fuelled engine</li>
      </ul>
    </div>
  );
}
body { padding: 0; margin: 0 }
body > div > div { padding: 20px; }
.avatar { border-radius: 50%; height: 90px; }

Запишіть вираз всередині фігурних дужок JSX

У наведеному нижче об'єкті повну URL-адресу зображення розділено на чотири частини: базову URL-адресу, imageId, imageSize та розширення файла.

Ми хочемо, щоб URL-адреса зображення поєднувала ці атрибути разом: базову URL-адресу (завжди 'https://i.imgur.com/'), imageId ('7vQD0fP'), imageSize ('s') та розширення файла (завжди '.jpg'). Однак, щось не так з тим, як тег <img> визначає свій src.

Чи можете ви це виправити?

const baseUrl = 'https://i.imgur.com/';
const person = {
  name: 'Gregorio Y. Zara',
  imageId: '7vQD0fP',
  imageSize: 's',
  theme: {
    backgroundColor: 'black',
    color: 'pink'
  }
};

export default function TodoList() {
  return (
    <div style={person.theme}>
      <h1>{person.name}'s Todos</h1>
      <img
        className="avatar"
        src="{baseUrl}{person.imageId}{person.imageSize}.jpg"
        alt={person.name}
      />
      <ul>
        <li>Improve the videophone</li>
        <li>Prepare aeronautics lectures</li>
        <li>Work on the alcohol-fuelled engine</li>
      </ul>
    </div>
  );
}
body { padding: 0; margin: 0 }
body > div > div { padding: 20px; }
.avatar { border-radius: 50%; }

Щоб перевірити, чи спрацювало виправлення, спробуйте змінити значення imageSize на 'b'. Зображення повинно змінитися після вашої зміни.

Ви можете записати його як src={baseUrl + person.imageId + person.imageSize + '.jpg'}.

  1. { відкриває вираз JavaScript
  2. .
  3. baseUrl + person.imageId + person.imageSize + '.jpg' створює правильний рядок URL
  4. } закриває вираз JavaScript
const baseUrl = 'https://i.imgur.com/';
const person = {
  name: 'Gregorio Y. Zara',
  imageId: '7vQD0fP',
  imageSize: 's',
  theme: {
    backgroundColor: 'black',
    color: 'pink'
  }
};

export default function TodoList() {
  return (
    <div style={person.theme}>
      <h1>{person.name}'s Todos</h1>
      <img
        className="avatar"
        src={baseUrl + person.imageId + person.imageSize + '.jpg'}
        alt={person.name}
      />
      <ul>
        <li>Improve the videophone</li>
        <li>Prepare aeronautics lectures</li>
        <li>Work on the alcohol-fuelled engine</li>
      </ul>
    </div>
  );
}
body { padding: 0; margin: 0 }
body > div > div { padding: 20px; }
.avatar { border-radius: 50%; }

Ви також можете винести цей вираз в окрему функцію, як getImageUrl нижче:

import { getImageUrl } from './utils.js'

const person = {
  name: 'Gregorio Y. Zara',
  imageId: '7vQD0fP',
  imageSize: 's',
  theme: {
    backgroundColor: 'black',
    color: 'pink'
  }
};

export default function TodoList() {
  return (
    <div style={person.theme}>
      <h1>{person.name}'s Todos</h1>
      <img
        className="avatar"
        src={getImageUrl(person)}
        alt={person.name}
      />
      <ul>
        <li>Improve the videophone</li>
        <li>Prepare aeronautics lectures</li>
        <li>Work on the alcohol-fuelled engine</li>
      </ul>
    </div>
  );
}
export function getImageUrl(person) {
  return (
    'https://i.imgur.com/' +
    person.imageId +
    person.imageSize +
    '.jpg'
  );
}
body { padding: 0; margin: 0 }
body > div > div { padding: 20px; }
.avatar { border-radius: 50%; }

Змінні та функції можуть допомогти вам спростити розмітку: