В мои первые дни (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 представляет собой не что иное, как функцию, и
- первый аргумент — тип html тег,
- второй аргумент — это объект, состоящий из атрибутов
- и третий аргумент — это дочерние элементы узла. Здесь у нас есть простой текст, как дети. Но вы можете представить себе более вложенных и сложных потомков.
Дети 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> )
Эта конструкция может показаться немного менее интуитивной для новичков, но после некоторого использования она покажется очень удобной.