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

时间:2018-10-29 14:50:01

标签: reactjs components short-circuiting

我有以下简单的短路语句,应显示一个组件或不显示任何内容:

{profileTypesLoading && <GeneralLoader />}

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

我做了一个console.log(profileTypesLoading)只是为了快速查看profileTypesLoading属性的状态,它的状态是预期的1或0。 0应该为假...什么也不会渲染。对吧?

知道为什么会这样吗?

4 个答案:

答案 0 :(得分:17)

由于您的条件是虚假的,因此不会返回第二个参数(<GeneralLoader />),因此它将返回profileTypesLoading,它是一个数字,因此react将渲染它,因为React跳过了任何渲染即typeof boolean or undefined,并将呈现typeof string or number的任何内容:

为了安全起见,您可以使用三元表达式{condition ? <Component /> : null}或布尔值将条件转换为{!!condition && <Component />}

答案 1 :(得分:3)

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 and falsy values

  

在JavaScript中,真实值是当   在布尔上下文中遇到。除非所有价值观都是真实的   被定义为伪造(即,除了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,因为它是a syntax extension to JavaScript。但是,问题是**

问题在于 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

答案 2 :(得分:0)

这将解决问题:

{!!profileTypesLoading && <GeneralLoader />}

因为它将0转换为false。原因是当它是0时,下一个条件没有被执行,它的行为就像JavaScript中的数字一样,因此双重否定在这里很有帮助。

答案 3 :(得分:0)

要首先评估错误条件,将 const 与三元结合使用是一种简单的方法。示例:

在这种情况下,如果 someCollectionProperty 为空,则会显示一个简单的按钮,否则将显示带有 some-options-menu 的按钮(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 视图可以避免使用这个