Особенности условного рендеринга в React
const Header: FC<{ id: number }> = ({ id }) => (
<ul>
<li><a href="/"</a>Главная</li>
<li><a href="/contacts"</a>Контакты</li>
{id && (
<li><a href="/somewhere">куда-то</a></li>
)}
</ul>
);Что здесь: передаем пропом число id, и если оно есть, то рендерим элемент списка.
Вроде бы все хорошо, но на самом деле опасно. Если id будет равен нулю, то компонент не отрендерится. Зато отрендерится 0.
То есть при id === 0на странице получится такая разметка
<ul> <li><a href="/"</a>Главная</li> <li><a href="/contacts"</a>Контакты</li>> 0 </ul>
Первый момент, что если при логическом операторе И (&&) один из операторов ложен, то он и вернется. То есть в нашем случае вернулся 0, т.к. число ноль при логическом преобразовании ложно.
0 && 1 // 0 2 && 3 // 3 1 && 0 && 2 // 0
Второй момент, что в реакте рендерятся числа. То есть вы можете сделать компонент, который возвращает число 0 и все нормально отобразится.
export const App = () => {
return 0;
}Другое дело, если бы вернулся не 0, а false — его реакт не отрендерит.
export const App = () => {
return false;
}Поэтому если хоть один логический оператор не булево значение, то я всегда оборачиваю аргументы в Boolean.
То есть в нашем случае лучше будет
const Header: FC<{ id: number }> = ({ id }) => (
<ul>
<li><a href="/"</a>Главная</li>
<li><a href="/contacts"</a>Контакты</li>
{Boolean(id) && (
<li><a href="/somewhere">куда-то</a></li>
)}
</ul>
);В логическом контексте, можно также преобразовать двойным отрицанием: !!
const Header: FC<{ id: number }> = ({ id }) => (
<ul>
<li><a href="/"</a>Главная</li>
<li><a href="/contacts"</a>Контакты</li>
{!!id && (
<li><a href="/somewhere">куда-то</a></li>
)}
</ul>
);