React 显示 0 而不是带有短路 (&&) 条件组件的空值

问题描述 投票:0回答:8

我有以下简单的短路语句,应该显示一个组件或什么都不显示:

{profileTypesLoading && <GeneralLoader />}

如果陈述是假的,它会呈现一个

0
而不是什么都没有。

我做了一个

console.log(profileTypesLoading)
只是为了快速查看
profileTypesLoading
属性的状态是什么,它是预期的 1 或 0。 0 应该是 false...导致不呈现任何内容。对吧?

知道为什么会这样吗?

reactjs components short-circuiting
8个回答
249
投票

由于您的条件是假的,因此不返回第二个参数(

<GeneralLoader />
),它将返回
profileTypesLoading
,这是一个数字,因此反应将渲染它,因为 React 会跳过任何
typeof
的渲染
boolean
undefined
并将呈现任何
typeof
string
number
:

为了安全起见,您可以使用三元表达式

{condition ? <Component /> : null}
或布尔值转换您的条件,例如
{!!condition && <Component />}


41
投票

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 本身如何处理 [truthyfalsy 值][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

16
投票

这将解决问题:

{!!profileTypesLoading && <GeneralLoader />}

因为它会将 0 转换为 false。原因是当它是

0
时,下一个条件不会被执行,它的行为就像 JavaScript 中的数字,所以双重否定在这里有帮助。


11
投票

您可以使用双 Bang (!!)。这将返回一个值的布尔真/假关联并且不会呈现 0.

{!!profileTypesLoading && <GeneralLoader/>}

7
投票

更直接的方法:

{Boolean(profileTypesLoading) && <GeneralLoader />}

0
投票

要首先评估错误条件,使用带有三元的 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 可以用这个来避免


0
投票

你可以绘制一个空的反应片段。

{profileTypesLoading ? <GeneralLoader /> : <></>}

-1
投票

这段代码

{ Boolean(profileTypesLoading) ? <GeneralLoader /> : <></> }

也解决了问题。由于我是初学者,我不知道这是否有缺点或副作用。

© www.soinside.com 2019 - 2024. All rights reserved.