Особенности условного рендеринга в React
Ревьюю студентов на курсах и часто натыкаюсь на общую проблему с условным рендерингом. Рассказываю.
Вот пишут такой реакт-компонент (для простоты убрал лишнее)
const List: FC<{ id: number }> = ({ id }) => (
<ul>
<li><a href="/">домой</a></li>
{id && (
<li><a href="/somewhere">куда-то</a></li>
)}
</ul>
);
Что здесь: передаем пропом число id
, и если оно есть, то рендерим элемент списка.
Вроде бы все хорошо, но на самом деле опасно. Если id
будет равен нулю, то компонент не отрендерится. Зато отрендерится 0
.
То есть при id === 0
на странице получится такая разметка
<ul>
<li><a href="/">домой</a></li>
0
</ul>
Почему так
Первый момент, что если при логическом операторе И (&&) один из операторов ложен, то он и вернется. То есть в нашем случае вернулся 0, т.к. число ноль при логическом преобразовании ложно.
0 && 1 // 0
2 && 3 // 3
1 && 0 && 2 // 0
Второй момент, что в реакте рендерятся числа. То есть вы можете сделать компонент, который возвращает число 0 и все нормально отобразится.
https://codesandbox.io/s/tender-colden-wfgtz?file=/src/App.jsДругое дело, если бы вернулся не 0, а false — его реакт не отрендерит.
https://codesandbox.io/s/sad-babbage-04ir9?file=/src/App.jsПоэтому если хоть один логический оператор не булево значение, то я всегда оборачиваю аргументы в Boolean
.
То есть в нашем случае лучше будет
const List: FC<{ id: number }> = ({ id }) => (
<ul>
<li><a href="/">домой</a></li>
{Boolean(id) && (
<li><a href="/somewhere">куда-то</a></li>
)}
</ul>
);
Доп. материалы на почитать: