Условный вывод
Вашим компонентам часто нужно отображать разные вещи в зависимости от различных условий. В React вы можете условно отображать JSX, используя синтаксис JavaScript, например, операторы if, &&, и ? :.
Вы узнаете
- Как возвращать разные JSX в зависимости от условия
- Как условно включать или исключать фрагмент JSX
- Общие сокращения условного синтаксиса, которые вы встретите в кодовых базах React
Условное возвращение JSX
Предположим, у вас есть компонент PackingList, отображающий несколько Itemов, которые могут быть помечены как упакованные или нет:
function Item({ name, isPacked }) { return <li className="item">{name}</li>; } export default function PackingList() { return ( <section> <h1>Sally Ride's Packing List</h1> <ul> <Item isPacked={true} name="Space suit" /> <Item isPacked={true} name="Helmet with a golden leaf" /> <Item isPacked={false} name="Photo of Tam" /> </ul> </section> ); }
Обратите внимание, что у некоторых компонентов Item свойство isPacked установлено в значение true, а не в false. Вы хотите добавить галочку (✅) к упакованным элементам, если isPacked={true}.
Вы можете записать это как оператор if/else, как показано ниже:
if (isPacked) {
return <li className="item">{name} ✅</li>;
}
return <li className="item">{name}</li>; Если свойство isPacked равно true, этот код возвращает другое дерево JSX. С этим изменением некоторые элементы получают галочку в конце:
function Item({ name, isPacked }) { if (isPacked) { return <li className="item">{name} ✅</li>; } return <li className="item">{name}</li>; } export default function PackingList() { return ( <section> <h1>Sally Ride's Packing List</h1> <ul> <Item isPacked={true} name="Space suit" /> <Item isPacked={true} name="Helmet with a golden leaf" /> <Item isPacked={false} name="Photo of Tam" /> </ul> </section> ); }
Попробуйте изменить то, что возвращается в каждом случае, и посмотрите, как изменится результат!
Обратите внимание, как вы создаете ветвящуюся логику с помощью операторов JavaScript if и return. В React обработка потока управления (например, условия) выполняется с помощью JavaScript.
Условное возвращение ничего с null
В некоторых ситуациях вы вообще не захотите ничего отображать. Например, предположим, что вы не хотите отображать упакованные элементы. Компонент должен возвращать что-то. В этом случае вы можете вернуть null:
if (isPacked) {
return null;
}
return <li className="item">{name}</li>; Если isPacked истинно, компонент не вернёт ничего, null. В противном случае он вернёт JSX для отображения.
function Item({ name, isPacked }) { if (isPacked) { return null; } return <li className="item">{name}</li>; } export default function PackingList() { return ( <section> <h1>Sally Ride's Packing List</h1> <ul> <Item isPacked={true} name="Space suit" /> <Item isPacked={true} name="Helmet with a golden leaf" /> <Item isPacked={false} name="Photo of Tam" /> </ul> </section> ); }
На практике возвращение null из компонента не является распространённой практикой, поскольку это может удивить разработчика, пытающегося отобразить его. Чаще вы условно включаете или исключаете компонент в JSX родительского компонента. Вот как это сделать!
Условное включение JSX
В предыдущем примере вы контролировали, какое (если таковое есть!) дерево JSX будет возвращено компонентом. Возможно, вы уже заметили некоторое дублирование в выходных данных рендеринга:
<li className="item">{name} ✅</li> очень похоже на
<li className="item">{name}</li> Оба условных блока возвращают <li className="item">...</li>:
if (isPacked) {
return <li className="item">{name} ✅</li>;
}
return <li className="item">{name}</li>; Хотя такое дублирование не вредно, оно может затруднить поддержку кода. Что, если вы захотите изменить className? Вам нужно будет внести изменения в двух местах в коде! В такой ситуации вы можете условно включить небольшой JSX, чтобы сделать свой код более DRY.
Условный (троичный) оператор (? :)
JavaScript имеет компактный синтаксис для написания условного выражения — условный оператор или «троичный оператор».
Вместо этого:
if (isPacked) {
return <li className="item">{name} ✅</li>;
}
return <li className="item">{name}</li>; Вы можете написать это:
return (
<li className="item">
{isPacked ? name + ' ✅' : name}
</li>
); Вы можете прочитать его как «если isPacked истинно, тогда (?) отобразить name + ' ✅', в противном случае (:) отобразить name».
Подробное изучение
Являются ли эти два примера полностью эквивалентными?
Если вы знакомы с объектно-ориентированным программированием, вы можете предположить, что два примера выше немного отличаются, потому что один из них может создать два разных «экземпляра» <li>. Но элементы JSX не являются «экземплярами», потому что они не содержат внутреннего состояния и не являются реальными узлами DOM. Они представляют собой лёгкие описания, как чертежи. Поэтому эти два примера, на самом деле, полностью эквивалентны. Сохранение и сброс состояния подробно описывает, как это работает.
Теперь предположим, что вы хотите обернуть текст завершённого элемента в другой тег HTML, например, <del> для его вычеркивания. Вы можете добавить ещё больше новых строк и скобок, чтобы было легче вкладывать больше JSX в каждый из случаев:
function Item({ name, isPacked }) { return ( <li className="item"> {isPacked ? ( <del> {name + ' ✅'} </del> ) : ( name )} </li> ); } export default function PackingList() { return ( <section> <h1>Sally Ride's Packing List</h1> <ul> <Item isPacked={true} name="Space suit" /> <Item isPacked={true} name="Helmet with a golden leaf" /> <Item isPacked={false} name="Photo of Tam" /> </ul> </section> ); }
Этот стиль хорошо подходит для простых условий, но используйте его с умеренностью. Если ваши компоненты становятся сложными из-за чрезмерного вложенного условного разметки, рассмотрите возможность выделения дочерних компонентов для очистки кода. В React разметка является частью вашего кода, поэтому вы можете использовать такие инструменты, как переменные и функции, чтобы упорядочить сложные выражения.
Оператор логического И (&&)
Ещё одно распространённое сокращение, которое вы встретите — оператор логического И JavaScript (JavaScript logical AND (&&) оператор).
Внутри компонентов React он часто появляется, когда вы хотите отобразить JSX, когда условие истинно, или не отображать ничего в противном случае. С &&, вы могли бы условно отобразить галочку только если isPacked равно true:
return (
<li className="item">
{name} {isPacked && '✅'}
</li>
); Вы можете прочитать это как «если isPacked, тогда (&&) отобразить галочку, в противном случае не отображать ничего».
Вот как это работает:
function Item({ name, isPacked }) { return ( <li className="item"> {name} {isPacked && '✅'} </li> ); } export default function PackingList() { return ( <section> <h1>Sally Ride's Packing List</h1> <ul> <Item isPacked={true} name="Space suit" /> <Item isPacked={true} name="Helmet with a golden leaf" /> <Item isPacked={false} name="Photo of Tam" /> </ul> </section> ); }
Выражение JavaScript && возвращает значение правой части (в нашем случае, галочки), если левая часть (наше условие) истинна. Но если условие ложно, всё выражение становится false. React рассматривает false как «пробел» в дереве JSX, как и null или undefined, и ничего не отображает на его месте.
Опасная ситуация
Не ставьте числа слева от &&.
Для проверки условия JavaScript автоматически преобразует левую часть в булево значение. Однако, если левая часть является 0, то всё выражение получает это значение (0), и React с удовольствием отобразит 0 вместо ничего.
Например, распространённая ошибка — написание кода, подобного messageCount && <p>New messages</p>. Легко предположить, что он отображает ничего, когда messageCount является 0, но на самом деле отображает 0.
Чтобы исправить это, сделайте левую часть булевым значением: messageCount > 0 && <p>New messages</p>.
Условное присваивание JSX переменной
Когда сокращения мешают написанию обычного кода, попробуйте использовать оператор if и переменную. Вы можете переопределять переменные, определённые с помощью let, поэтому начните с предоставления значения по умолчанию, которое вы хотите отобразить, и имени:
let itemContent = name; Используйте оператор if для переопределения выражения JSX в itemContent, если isPacked равно true:
if (isPacked) {
itemContent = name + " ✅";
} Фигурные скобки открывают «окно в мир JavaScript». Вставьте переменную с фигурными скобками в возвращаемое дерево JSX, вложив ранее вычисленное выражение внутри JSX:
<li className="item">
{itemContent}
</li> Этот стиль является самым объёмным, но и самым гибким. Вот пример его работы:
function Item({ name, isPacked }) { let itemContent = name; if (isPacked) { itemContent = name + " ✅"; } return ( <li className="item"> {itemContent} </li> ); } export default function PackingList() { return ( <section> <h1>Sally Ride's Packing List</h1> <ul> <Item isPacked={true} name="Space suit" /> <Item isPacked={true} name="Helmet with a golden leaf" /> <Item isPacked={false} name="Photo of Tam" /> </ul> </section> ); }
Как и прежде, это работает не только для текста, но и для произвольного JSX:
function Item({ name, isPacked }) { let itemContent = name; if (isPacked) { itemContent = ( <del> {name + " ✅"} </del> ); } return ( <li className="item"> {itemContent} </li> ); } export default function PackingList() { return ( <section> <h1>Sally Ride's Packing List</h1> <ul> <Item isPacked={true} name="Space suit" /> <Item isPacked={true} name="Helmet with a golden leaf" /> <Item isPacked={false} name="Photo of Tam" /> </ul> </section> ); }
Если вы не знакомы с JavaScript, этот набор стилей может показаться подавляющим на первый взгляд. Однако изучение их поможет вам читать и писать любой код JavaScript — и не только компоненты React! Выберите тот, который вам больше нравится, а затем снова просмотрите эту справку, если забудете, как работают другие.
Резюме
- В React вы управляете ветвлением логики с помощью JavaScript.
- Вы можете условно возвращать выражение JSX с помощью оператора
if. - Вы можете условно сохранить JSX в переменную, а затем включить её в другой JSX, используя фигурные скобки.
- В JSX,
{cond ? <A /> : <B />}означает «еслиcond, отобразить<A />, в противном случае<B />». - В JSX,
{cond && <A />}означает «еслиcond, отобразить<A />, в противном случае ничего». - Сокращения распространены, но вы не обязаны их использовать, если предпочитаете обычный
if.
Попробуйте выполнить некоторые задания
Задание 1 из 3:
Отобразить значок для незавершенных элементов с ? :
Используйте условный оператор (cond ? a : b) для отображения ❌, если isPacked не равно true.
function Item({ name, isPacked }) { return ( <li className="item"> {name} {isPacked && '✅'} </li> ); } export default function PackingList() { return ( <section> <h1>Sally Ride's Packing List</h1> <ul> <Item isPacked={true} name="Space suit" /> <Item isPacked={true} name="Helmet with a golden leaf" /> <Item isPacked={false} name="Photo of Tam" /> </ul> </section> ); }
© 2013–present Facebook Inc.
Licensed under the Creative Commons Attribution 4.0 International Public License.
https://react.dev/learn/conditional-rendering