JSX: когда оцениваются выражения JavaScript? - PullRequest
0 голосов
/ 29 января 2019

После изучения руководств по GatsbyJS и React у меня сложилось впечатление, что выражения JavaScript всегда оцениваются, когда они заключены в {} скобки в JSX.Но теперь я смотрю на файл JSX внутри репозитория GatsbyJS, где выглядит, как будто скобки вызывают другое поведение:

const {
    data: {
      posts: { edges: posts },
      site: {
        siteMetadata: { facebook }
      }
    }
} = props;

( Источник )

Согласно учебным пособиям, «facebook» должен оцениваться как JavaScript и должен возвращать undefined, но это не то, что происходит.Каким-то образом мы получаем объект JavaScript data.site.siteMetadata.facebook, в котором есть некоторые данные.Что тут происходит?Почему «facebook» не оценивается как выражение JavaScript?

1 Ответ

0 голосов
/ 29 января 2019

Кусок кода, который вы копируете, на самом деле не имеет ничего общего с JSX (см. Ниже).Это ES6 синтаксис разрушения объектов , как прокомментировал вопрос @PrithvirajSahu.

Скажем, у вас есть такой объект:

const obj = {
  a: 100, 
  b: { 
    value: 200,
  } 
};

Вы можете получить внутренние значения следующим образом:

const { a } = obj; 
// same as const a = obj.a

const { b: c } = obj; 
// same as const c = obj.b

const { b: { value } } = obj; 
// same as const value = obj.b.value

const { b: { value: v } } = obj; 
// same as const v = obj.b.value

const { a, { b: { value } } } = obj; 
// same as 
// const a = obj.a; 
// const value = obj.b.value;

Итак, вернемся к вашему коду кода, этоэквивалентно

const posts = props.data.posts.edges;
const facebook = props.data.site.siteMetadata.facebook;

Как вы узнали, синтаксис деструктурирования очень аккуратен на 1 или, возможно, 2 уровнях, но трудно читается, когда их больше.Лично я использую его только на 1 уровне.


Редактировать : В функции в источнике только строки, начинающиеся с <..., имеют синтаксис JSX.

const CategoryPage = props => {
  // code here is normal js
  const { ... } = props;

  // JSX start from inside this return function
  return (
    <React.Fragment>
      { /* code between bracket in this section will be evaluate as 'normal JS' */ }
    </React.Fragment>
  )
}

Предостережение: код в скобках в JSX должен вычислять функцию.Если мы напишем что-то вроде этого:

<div className="container">
  Hello
  {"Happy"}
  World
</div>

Babel превратит его в следующий обычный JS:

React.createElement(
  "div",
  { className: "container" },
  "Hello",
  "Happy",
  "World"
);

Играйте с Babel здесь

Все, что мы поместим между скобками, будет передано React.createElement как дочерний элемент div;поэтому здесь может быть размещен только действительный элемент React:

  • Null (ничего не отображать)
  • Строка (станет текстовым узлом DOM)
  • Другой элемент React
  • Выражение / функция, которая оценивает или возвращает любое из вышеперечисленных
<div>
  { hasDate && <Date /> }
<div>

или

// somewhere in the code
const showDate = (hasDate) => {
  if (!hasDate) return null;
  return <Date />
}

// in the render function
return (
  <div>
    { showDate(hasDate) }
  <div>
)

Мы также можем использовать скобки для передачи значения вреквизиты элемента:

<div 
  style={ { color: 'red' } }
  onClick={ (event) => {...} }>
  { hasDate && <Date /> }
<div>
...