用短路(& &)条件分量反应显示0而不是什么都没有

我有以下简单的短路声明,要么显示一个组件,要么什么都不显示:

{profileTypesLoading && <GeneralLoader />}

如果语句为 false,它将呈现 0而不是什么都不呈现。

我已经做了一个 console.log(profileTypesLoading),只是为了快速查看 profileTypesLoading属性的状态,它可能是1,也可能是0。0应该是错误的... 导致没有任何渲染。对吧?

知道为什么会这样吗?

36180 次浏览

这将解决问题:

{!!profileTypesLoading && <GeneralLoader />}

因为它会将0转换为 false。原因是当它是 0时,下一个条件不会被执行,而且它的行为类似于 JavaScript 中的数字,所以双重否定在这里很有帮助。

因为你的条件是假的,所以不返回第二个参数(<GeneralLoader />) ,它将返回 profileTypesLoading,这是一个数字,所以反应将呈现它,因为反应跳过任何是 ABC2 ABC3或 undefined的渲染,将呈现任何是 ABC2 ABC6或 number的:

为了确保安全,您可以使用三元表达式 {condition ? <Component /> : null}或布尔强制转换您的条件,如 {!!condition && <Component />}

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

TLDR

这是因为 javascript 本身处理[ 真心话假的值][1]的方式:

在 JavaScript 中,true 值是在以下情况下被认为为 true 的值 所有值都是真值,除非它们 被定义为 false (即,除 false 外,0、“”、 null、未定义、, 及 NaN)。

& & 运算符一起使用时,返回的值取决于左边的值:

  • 如果左边的值为真,则返回右边的值。
  • 如果左值为 false,则返回其值。

例子:

// 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

要首先计算一个假条件,使用带有三值的 const 是一种简单的方法。例如:

在这种情况下,如果 somCollecctionProperty 为空 else,则显示一个简单的按钮,并显示一个带有 some-options-menu 的按钮(材质 UI 示例)

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 />}

您可以使用 double Bang (! !).这将返回值的布尔值 true/false 关联,并且不会呈现0。

{!!profileTypesLoading && <GeneralLoader/>}