fasaas
fasaas

Reputation: 702

ReactJs - Conditional Rendering or hiding component

What's the de facto approach to choosing between conditional rendering or hiding the component with { display: 'none' }?

For the sake of discussion, let's say that I have a FilterComponent that holds the title of the filter, and a list of FilterItems, with name and amount.

In short, a FilterComponent could be:

Color

When hitting Show More button, more FilterItems will be displayed, i.e.

Color

Should I hide the FilterItems that are below the Show More? Or should I return null for those below and render them after updating the state with Show More?

Upvotes: 13

Views: 20946

Answers (9)

tolotra
tolotra

Reputation: 3270

An other approach based on Array.prototype.slice() method

The usage in parent component

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

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

And the ColorList component looks like this:

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>
    </>
  );
}

Note: I uploaded the code on CodeSandbox, you can check it here

Upvotes: 0

Abdelhadi Abdo
Abdelhadi Abdo

Reputation: 412

My prefer two methodes:

#1 Element Variables

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>
}

More details here: https://reactjs.org/docs/conditional-rendering.html

Upvotes: 2

Limbo
Limbo

Reputation: 2290

Generally, there is no significant performance differences between display: none and conditional rendering, because the browser's behaviour in both cases is nearly the same. The main difference is that if you use display: none, then node is not removing from the DOM tree, which forces some CSS pseudo-selectors like :last-child to consider a hidden node as last-child and so on. So, it is not performance-related, but mostly CSS-related. Both of approaches are ok for use, I suppose :)

Upvotes: 0

Alican &#199;elik
Alican &#199;elik

Reputation: 63

You can change initial state value of isHidden or something like that . When you click button value will be oppasite of before situtation . And when you wants to render you should give condition ;

{ isHidden &&

...

Upvotes: 2

Ramiro Estrella
Ramiro Estrella

Reputation: 1

You could use a library called react-if. This library helps you wether to render or not based on a a condition.

Here is an example:

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> )

Upvotes: -1

Neal
Neal

Reputation: 673

I think there are a few ways to accomplish what you need. However, this seems to be the most practised:

{myConditionIsTrue && <MyComponent />}

In your case, it makes sense to use state. I would have a prop inside FilterComponent called showFullList

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

Just be weary, this mechanism is actually removing/adding to the DOM.

Upvotes: 19

Ryan Cogswell
Ryan Cogswell

Reputation: 81066

Generally in React it is better to not render something than to render it as hidden. Here is one related discussion: https://discuss.reactjs.org/t/conditional-rendering-or-toggling-hidden-classes/2535/6

Upvotes: 3

Naismith
Naismith

Reputation: 266

It would make more sense to not render the items that should not be shown until after the Show More has been clicked, and the state has updated. This way you can handle how many items should be shown by default before clicking Show More. This way instead of applying inline styles, or a special class to certain elements, you can use the exact same logic to all FilterItems, but only render X of them.

Upvotes: 1

weibenfalk
weibenfalk

Reputation: 892

I would go for the "updating state" approach. That way you always have the actual filterItems that is showing in the state. So your components state is in sync and represents the current UI that is showing.

Guess there's no right or wrong in this question though =)

Upvotes: 1

Related Questions