ReactJs-有条件的渲染或隐藏组件

时间:2018-11-22 13:52:30

标签: reactjs conditional-rendering

在条件渲染或使用{ display: 'none' }隐藏组件之间进行选择的实际方法是什么?

为便于讨论,假设我有一个FilterComponent,其中保存了过滤器的title,还有一个FilterItems的列表,其中包含name和{ {1}}。

简而言之,amount可能是:

颜色

  • 蓝色(19)
  • 黄色(17)
  • 橙色(3)
  • 黑色(7)
  • 绿色(10)

    FilterComponent

按下+ Show More按钮时,将显示更多Show More,即

颜色

  • 蓝色(19)
  • 黄色(17)
  • 橙色(3)
  • 黑色(7)
  • 绿色(10)
  • 布朗(17)
  • 粉红色(88)
  • 白色(55)
  • 红色(32)
  • 紫色(17)

    FilterItem

我应该隐藏- Show Less下面的FilterItem吗?还是我应该为下面的那些返回null并在用Show More更新状态后呈现它们?

9 个答案:

答案 0 :(得分:1)

我会采用“更新状态”方法。这样,您始终可以获得状态中显示的实际filterItems。因此,您的组件状态是同步的,并表示正在显示的当前UI。

猜猜这个问题没有对与错=)

答案 1 :(得分:1)

在单击“显示更多”并且状态已更新之前,不渲染不应显示的项目会更有意义。这样,您可以处理默认情况下应显示多少项,然后单击+------+------+------+---------------------+---------------------+ | ID_1 | ID_2 | ID_3 | enter | exit | +------+------+------+---------------------+---------------------+ | 1 | A | I | 17/01/2013 15:37:25 | 28/01/2013 11:22:59 | | 1 | B | II | 13/06/2013 22:23:54 | 25/06/2013 13:35:51 | | 1 | B | II | 25/06/2013 14:45:21 | 05/07/2013 17:11:30 | | 1 | B | II | 05/07/2013 21:33:30 | 11/11/2013 12:00:00 | | 1 | C | III | 09/03/2014 00:14:31 | 05/04/2014 12:12:51 | +------+------+------+---------------------+---------------------+ 。这样,您可以对所有Show More使用完全相同的逻辑,而不是对某些元素应用内联样式或特殊类,而只能渲染其中的FilterItems

答案 2 :(得分:1)

通常,在React中,最好不要渲染某些东西,而不要渲染为隐藏的东西。这是一个相关的讨论: https://discuss.reactjs.org/t/conditional-rendering-or-toggling-hidden-classes/2535/6

答案 3 :(得分:1)

我认为有几种方法可以满足您的需求。但是,这似乎是最实用的方法:

{myConditionIsTrue && <MyComponent />}

在您的情况下,使用状态很有意义。我将在FilterComponent内部有一个名为showFullList

的道具
{this.state.showFullList && (
 <React.Fragment>
   <All/><The/><Other/><Components/>
</React.Fragment>)}

只是感到疲倦,这种机制实际上是在删除/添加到DOM。

答案 4 :(得分:1)

您可以更改isHidden的初始状态值或类似的值。当您单击按钮时,值将与选址之前相反。当你想渲染的时候应该给条件;

{ isHidden &&

...

答案 5 :(得分:0)

通常,display: none和条件渲染之间没有明显的性能差异,因为在两种情况下浏览器的行为几乎相同。主要区别在于,如果使用display: none,则不会从DOM树中删除节点,这会迫使某些:last-child之类的CSS伪选择器将隐藏节点视为最后一个子节点,依此类推。因此,它与性能无关,但主要与CSS有关。我想这两种方法都可以使用:)

答案 6 :(得分:0)

我更喜欢两种方法:

#1 元素变量

const button = <LogoutButton onClick={this.handleLogoutClick} />;

<div>
    <Greeting isLoggedIn={isLoggedIn} />
    {button}
</div>

2# Inline If with Logical && Operator

{unreadMessages.length > 0 &&
    <h2>
        You have {unreadMessages.length} unread messages.
    </h2>
}

此处有更多详细信息:https://reactjs.org/docs/conditional-rendering.html

答案 7 :(得分:0)

另一种基于 Array.prototype.slice() 方法的方法

父组件中的使用

import React from "react";
import { ColorList } from "./Color";

export default function App() {
  return <ColorList colors={["red", "green", "blue"]} visibleItemsCount={1} />;
}

ColorList 组件如下所示:

import React from "react";

// This is just a placeholder component :)
function Color({ color }) {
  return <div style={{ color }}>{color}</div>;
}

export function ColorList({ colors, visibleItemsCount = 0 }) {
  const [showMore, setShowMore] = React.useState(false);

  // Toggle value on click button
  const onClick = () => setShowMore((value) => !value);

  // Memoize the color list when props changed
  const visibleColors = React.useMemo(() => {
    // If show more items, return the whole array
    // Otherwise, return a sliced array based on visible items
    const count = showMore ? colors.count : visibleItemsCount;
    return colors.slice(0, count);
  }, [colors, visibleItemsCount, showMore]);

  console.log(visibleColors);
  return (
    <>
      <h1>Color list</h1>
      <>
        {visibleColors.map((color) => (
          <Color key={color} color={color} />
        ))}
      </>
      <button onClick={onClick}>{showMore ? "Show less" : "Show more"}</button>
    </>
  );
}

注意:我把代码上传到CodeSandbox,你可以查看here

答案 8 :(得分:-1)

您可以使用一个名为react-if的库。该库可帮助您根据条件是否渲染。

这里是一个例子:

const Bar = ({ name, age, drinkingAge }) => (
    <div>
        <Header />
        <If condition={ age >= drinkingAge }>
            <Then><span className="ok">Have a beer, {name}!</span></Then>
            <Else><span className="not-ok">Sorry, {name}, you are not old enough.</span></Else>
        </If>
        <Footer />
    </div> )