У меня есть следующий простой оператор короткого замыкания, который должен показывать либо компонент, либо ничего:
{profileTypesLoading && <GeneralLoader />}
Если утверждение ложно, оно отображает 0 вместо ничего.
Я сделал console.info(profileTypesLoading), чтобы быстро увидеть, каков статус свойства profileTypesLoading, и он либо 1, либо 0, как и ожидалось. 0 должен быть ложным ... ничего не выводить. Верно?
Есть идеи, почему это могло произойти?





Это решило бы проблему:
{!!profileTypesLoading && <GeneralLoader />}
Поскольку он преобразует 0 в false. Причина в том, что когда это 0, следующее условие не выполняется, и оно ведет себя как число в JavaScript, поэтому здесь помогает двойное отрицание.
Поскольку ваше условие является ложным и поэтому не возвращает второй аргумент (<GeneralLoader />), оно вернет profileTypesLoading, которое является числом, поэтому react будет отображать его, потому что React пропускает рендеринг для всего, что является typeofboolean или undefined, и будет отображать все, что typeofstring или number:
Чтобы сделать его безопасным, вы можете использовать тернарное выражение {condition ? <Component /> : null} или логическое преобразование вашего условия, например {!!condition && <Component />}
Я приму это, как только мне позволят через 3 минуты ... но спасибо, это имеет смысл. Я удивлен, что этого нет ни в одном из объяснений, которые я читал по этому методу. Это всегда писалось так, как писала я. Без кастинга. Урок выучен!
Вы также можете использовать оператор Boolean, если !!condition вас смущает. Что-то вроде { Boolean(condition) && <Component /> }
таблица истинности реакции: jsfiddle.net/milahu/k2z3wocm/5
0 является ложным значением, поэтому, когда оно оценивается &&, оно возвращает 0. Однако 0 может отображаться в React, потому что это число:
// Renderable values
1 && <GeneralLoader /> // => Renders <GeneralLoader />
"a string" && <GeneralLoader /> // => Renders <GeneralLoader />
0 && <GeneralLoader /> // => Renders '0'
// Non-renderable values
false && <GeneralLoader /> // => Renders nothing
null && <GeneralLoader /> // => Renders nothing
undefined && <GeneralLoader /> // => Renders nothing
TL; DR
Это связано с тем, как сам javascript обрабатывает [значения правдивый и ложь] [1]:
In JavaScript, a truthy value is a value that is considered true when encountered in a Boolean context. All values are truthy unless they are defined as falsy (i.e., except for false, 0, "", null, undefined, and NaN).
При использовании с оператором && возвращаемое значение зависит от левого значения:
Примеры:
// Truthy values
1 && "hello" // => "hello"
"a string" && "hello" // => "hello"
// Falsy values
0 && "hello" // => 0
false && "hello" // => false
null && "hello" // => null
undefined && "hello" // => undefined
Те же правила применяются к JSX, потому что это [расширение синтаксиса JavaScript] [2]. Однако проблема в том, что **
Проблема в том, что 0 является ложным значением, поэтому, когда оно оценивается &&, оно возвращает 0. Однако 0 обрабатывается React, потому что это число
// Renderable values
1 && <GeneralLoader /> // => Renders <GeneralLoader />
"a string" && <GeneralLoader /> // => Renders <GeneralLoader />
0 && <GeneralLoader /> // => Renders 0
// Non-renderable values
false && <GeneralLoader /> // => Renders nothing
null && <GeneralLoader /> // => Renders nothing
undefined && <GeneralLoader /> // => Renders nothing
Чтобы сначала оценить ложное условие, можно легко использовать константу с тернарностью. Пример:
В этом случае отображается простая кнопка, если someCollecctionProperty пуст, иначе будет отображаться кнопка с меню некоторых параметров (пример пользовательского интерфейса материала)
export default function MyComponent({ obj }) {
const jsxResponse = !obj.someCollecctionProperty.length ? <Button>No Action</Button>
:
<>
<Button
aria-label = "more"
aria-controls = "long-menu"
aria-haspopup = "true"
variant = "contained"
onClick = {handleClick}
color = {'primary'}>
<ThumbUpAltOutlinedIcon/>OK
</Button>
<Menu
id = "long-menu"
anchorEl = {anchorEl}
keepMounted
open = {open}
onClose = {handleClose}
>
{obj.someCollecctionProperty.map((option) => (
<MenuItem key = {option.id} onClick = {handleClose}>
<Avatar variant = "square" alt = {option.name} src = {option.url}/>{option.configName}
</MenuItem>
))}
</Menu>
</>;
return (<div>{jsxResponse}</div>);
}
jsxResponse - это визуализированный компонент, 0 при просмотре можно избежать с помощью этого
Более простой подход:
{Boolean(profileTypesLoading) && <GeneralLoader />}
Вы можете использовать двойной удар (!!). Это возвращает логическое значение true / false для значения и не отображает 0.
{!!profileTypesLoading && <GeneralLoader/>}
Вы также можете использовать
{profileTypesLoading > 0 && <GeneralLoader />}как React docs говорит