В мои первые дни (React), после просмотра нескольких примеров, я использовал jsx и выполнил свою работу. Но потребовалось некоторое время, чтобы освоить концепцию. И в процессе есть моменты «ага», которыми я сейчас поделюсь.

Петля

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

<ol>
{
  data.map(item => <data key={item.id}> {item.label}</data>)
}
</ol>

Это выглядит довольно просто. Я хотел добиться того же результата, используя оператор for. Я пробовал ниже и потерпел неудачу.

<ol>
{
  for(let i = 0; i < data.length; i++) {
    <data key={item.id}> {item.label}</data>
  }
</ol>

Мне было интересно, почему он не работает, даже если он выглядит очень интуитивно понятным.

Я перечитал документацию JSX, чтобы лучше понять.

JSX — это не технология сама по себе. Это просто «синтаксический сахар», в котором вызовы функций представлены в виде тегов для простоты чтения и записи. Вот и все.

<div className="info">Hello and Welcome</div>

Приведенная ниже функция является эквивалентом приведенной выше функции jsx.

React.createElement(
  'div',
  {className: 'info'},
  'Hello and Welcome'
)

Таким образом, каждый узел jsx представляет собой не что иное, как функцию, и

  1. первый аргумент — тип html тег,
  2. второй аргумент — это объект, состоящий из атрибутов
  3. и третий аргумент — это дочерние элементы узла. Здесь у нас есть простой текст, как дети. Но вы можете представить себе более вложенных и сложных потомков.

Дети jsx могут быть только выражениями, но не операторами.

Это причина, по которой у нас не может быть цикла for в дочерних элементах. Выражение оценивается как значение. Заявления нет.

Позвольте мне повторить. При написании jsx динамическая часть (или javascript) записывается в фигурных скобках ({}). И это всегда должно быть выражением, а не утверждением.

дети

По мере роста приложения будет несколько уровней вложенности компонентов.

const InnerMost = (props) => <div>....</div>
const Inner = (props) => <div>... <InnerMost/> ... </div>
const Outer = (props) => <div>... <Inner/> ... </div>

Приведенный выше код не настоящий, а просто символический. Здесь дело в том, что «внешний» компонент содержит «внутренний» компонент, который, в свою очередь, содержит компонент «InnerMost».

Основная проблема в этой конструкции заключается в том, что между компонентами «Outer» и «InnerMost» сложно общаться. Очень часто нам может понадобиться передать реквизит во вложенную структуру. Практика новичков заключается в передаче реквизита компоненту «Внутренний», который, в свою очередь, перейдет к компоненту «InnerMost». Неудобная часть при этом заключается в том, что «внутренний» компонент не требует и не использует реквизиты, а просто передает его дочернему компоненту. И этого ненужного «перехода» можно избежать, используя «props.children», как показано ниже.

const InnerMost = (props) => <div>....</div>
const Inner = (props) => <div>... {props.children} ... </div>
const Outer = (props) => (
  <div>
    ... 
    <Inner> 
      ...<InnerMost/> ... 
    </Inner> 
    ... 
  </div>
)

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