仅部分发生反应条件渲染

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

我有一个react组件,它将数组的结果显示为Badge(来自Bootstrap React库)。在这种情况下,我正在检查数组的长度是否大于零,并使用map函数呈现结果。我想添加其他文本以在条件上也显示,但由于某些原因,它没有显示h1标签,但仍在显示徽章。为什么不显示h1标签?

render() {
   const arr = this.state.items;
   return( 
    <Card>
     <Card.Body>
      <div>
       {arr.length > 0 && <h1>Additional Text</h1> &&
        arr.map((item) => 
        <Badge key={item.toString()} pill variant='primary'>
          {item}
        </Badge>
       }
     </div>
    </Card.Body>
   </Card>
);
javascript reactjs react-bootstrap
5个回答
3
投票

[您正在使用And short circuit evaluation,它对每个表达式求值(在&&之前),如果它是假的,则返回结果;如果所有其他都是真,则返回最后一个。

在这种情况下,整个表达式的结果是存在数组时映射的乘积,因为H1表达式会生成一个对象,这始终是真实的。

同样使用两个单独的表达式来渲染H1:

render() {
   const arr = this.state.items;
   return( 
    <Card>
     <Card.Body>
      <div>
       {arr.length > 0 && <h1>Additional Text</h1>}
       {arr.length > 0 &&
        arr.map((item) => 
        <Badge key={item.toString()} pill variant='primary'>
          {item}
        </Badge>
       }
     </div>
    </Card.Body>
   </Card>
);

另一个选择是将所有条件渲染的表达式移至另一个函数,并在表达式为真时调用它:

renderBadges(arr) {
  return (
    <>
      <h1>Additional Text</h1>
      {arr.map((item) => (
        <Badge key={item.toString()} pill variant='primary'>
          {item}
        </Badge>
      )}
    </>
  );
}

render() {
   const arr = this.state.items;
   return( 
    <Card>
     <Card.Body>
      <div>
       {arr.length > 0 && this.renderBadges(arr)}
     </div>
    </Card.Body>
   </Card>
);

1
投票

这是因为arr.length > 0 && <h1>Additional Text</h1>的计算结果为true,您会看到标记。

更干净的方法是做这样的事情(只是一个建议,还有许多其他可能且同样正确的方法):

const getPills = (items) => {
    const pills = [<h1>Additional Text</h1>];
    items.forEach(item => {
        pills.push(
            <Badge key={item.toString()} pill variant='primary'>
                {item}
            </Badge>
        );
    })
    return pills;
};

render() {
   const arr = this.state.items;
   return( 
    <Card>
     <Card.Body>
      <div>
       {arr.length ? getPills(arr) : ''}
     </div>
    </Card.Body>
   </Card>
);

1
投票

尝试将具有相同条件的内容包装到div中,因此无需重复条件,例如:

render() {
   const arr = this.state.items;
   return( 
    <Card>
     <Card.Body>
       {arr.length > 0 && (
       <div>
        <h1>Additional Text</h1>
        {arr.map((item) => 
          <Badge key={item.toString()} pill variant='primary'>
            {item}
          </Badge>
        }
       </div>)
    </Card.Body>
   </Card>
);

1
投票

因为&&检查其先前的条件或陈述为真实

 render() {
 const arr = this.state.items;
 return( 
  <Card>
   <Card.Body>
    <div>
   {arr.length > 0 && <> <h1>Additional Text</h1>
    arr.map((item) => 
    <Badge key={item.toString()} pill variant='primary'>
      {item}
    </Badge>
    </>
   }
  </div>
 </Card.Body>
 </Card>
);

0
投票

据我所知,您正在尝试使用条件语句错误。从文档here

expr1 && expr2表示如果expr1可以转换为true,则返回expr2;否则,返回expr1

即您的第一个表达式arr.length > 0返回true,因此, 您的第二个表达式的计算结果为<h1>...</h1>,它的计算结果也为true。因此,将评估并返回最终表达式。

因此,为了显示这两个组件,您可以使用片段,也可以像其他人建议的那样使用多个条件或包装在div中。

{
  arr.length > 0 && 
  <>
  <h1>Additional Text</h1>
  {
     arr.map((item) => 
        <Badge key={item.toString()} pill variant='primary'>
          {item}
        </Badge>
  }
  </>        
}

这里,<></><React.Fragment></React.Fragment>的简写,将为您提供您想要的树状结构。

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