ReactJs - 条件渲染或隐藏组件

ReactJs - Conditional Rendering or hiding component

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

为了便于讨论,假设我有一个 FilterComponent,其中包含过滤器的 title,以及一个 FilterItems 的列表,其中 nameamount.

简而言之,FilterComponent 可能是:

颜色

点击Show More按钮时,会显示更多FilterItem,即

颜色

我应该隐藏 Show More 下面的 FilterItem 吗?或者我应该 return 为下面的人设置 null 并在使用 Show More?

更新状态后渲染它们

我会选择 "updating state" 方法。这样,您始终拥有在状态中显示的实际 filterItems。因此,您的组件状态是同步的,代表当前正在显示的 UI。

虽然猜猜这个问题没有对错=)

在单击“显示更多”并且状态已更新之前,不呈现不应显示的项目会更有意义。通过这种方式,您可以处理在单击 Show More 之前默认应显示多少项。通过这种方式,您可以对所有 FilterItems 使用完全相同的逻辑,而不是对某些元素应用内联样式或特殊 class,但只渲染其中的 X

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

您可以使用名为 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> )

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

{myConditionIsTrue && <MyComponent />}

在您的情况下,使用状态是有意义的。我会在 FilterComponent 中有一个名为 showFullList

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

累了,这个机制其实是removing/adding到DOM。

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

{ isHidden &&

...

通常,display: none 和条件呈现之间没有显着的性能差异,因为浏览器在这两种情况下的行为几乎相同。主要区别在于,如果您使用 display: none,则节点不会从 DOM 树中删除,这会迫使某些 CSS pseudo-selectors 像 :last-child 考虑隐藏节点如 last-child 等。所以,它不是 performance-related,但主要是 CSS-related。我想这两种方法都可以使用:)

我更喜欢两种方法:

#1 元素变量

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

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

2# 内联 If 与逻辑 && 运算符

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

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

另一种基于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