我有以下简单的短路语句,应该显示一个组件或什么都不显示:
{profileTypesLoading && <GeneralLoader />}
如果陈述是假的,它会呈现一个
0
而不是什么都没有。
我做了一个
console.log(profileTypesLoading)
只是为了快速查看 profileTypesLoading
属性的状态是什么,它是预期的 1 或 0。 0 应该是 false...导致不呈现任何内容。对吧?
知道为什么会这样吗?
由于您的条件是假的,因此不返回第二个参数(
<GeneralLoader />
),它将返回profileTypesLoading
,这是一个数字,因此反应将渲染它,因为 React 会跳过任何 typeof
的渲染boolean
或 undefined
并将呈现任何 typeof
string
或 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 本身如何处理 [truthy 和 falsy 值][1]:
在 JavaScript 中,真值是在以下情况下被认为是真的值 在布尔上下文中遇到。所有值都是真实的,除非它们 被定义为 falsy(即除了 false、0、""、null、undefined、 和 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
这将解决问题:
{!!profileTypesLoading && <GeneralLoader />}
因为它会将 0 转换为 false。原因是当它是
0
时,下一个条件不会被执行,它的行为就像 JavaScript 中的数字,所以双重否定在这里有帮助。
您可以使用双 Bang (!!)。这将返回一个值的布尔真/假关联并且不会呈现 0.
{!!profileTypesLoading && <GeneralLoader/>}
更直接的方法:
{Boolean(profileTypesLoading) && <GeneralLoader />}
要首先评估错误条件,使用带有三元的 const 是一种简单的方法。例子:
在这种情况下,如果 someCollecctionProperty 为空,则显示一个简单的按钮,否则,将显示一个带有一些选项菜单的按钮(Material 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
on view 可以用这个来避免
你可以绘制一个空的反应片段。
{profileTypesLoading ? <GeneralLoader /> : <></>}
这段代码
{ Boolean(profileTypesLoading) ? <GeneralLoader /> : <></> }
也解决了问题。由于我是初学者,我不知道这是否有缺点或副作用。