React.js
Web Development
JavaScript
User Interface
Front-end Development

Show or hide element in React

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

In React, "show or hide an element" can mean two different things: remove it from the render tree entirely, or keep it mounted and only change its visibility. Those two choices look similar in the browser, but they have very different behavior for state, effects, layout, and accessibility.

The right solution depends on what you want the UI to do. If the element should not exist at all, conditionally render it. If it should stay mounted and preserve state, hide it with CSS or a visibility-related attribute.

Conditional Rendering Removes the Element

The most common React pattern is conditional rendering. If the condition is false, React does not render the element at all.

jsx
1function WelcomeMessage({ isLoggedIn }) {
2  return (
3    <section>
4      {isLoggedIn && <h1>Welcome back</h1>}
5    </section>
6  );
7}

This works well for UI that should appear only in one state, such as:

  • authenticated versus unauthenticated content
  • loading states
  • error banners
  • optional panels

You can also use a ternary when there are two alternate branches:

jsx
function AuthButton({ isLoggedIn }) {
  return isLoggedIn ? <button>Log out</button> : <button>Log in</button>;
}

Conditional rendering is usually the best choice when the element truly should not be in the DOM.

Use State to Control Visibility

Most show-or-hide interactions are driven by component state.

jsx
1import { useState } from "react";
2
3export default function DetailsPanel() {
4  const [open, setOpen] = useState(false);
5
6  return (
7    <div>
8      <button onClick={() => setOpen((value) => !value)}>
9        {open ? "Hide details" : "Show details"}
10      </button>
11
12      {open && <p>The details are now visible.</p>}
13    </div>
14  );
15}

This is the normal pattern for accordions, disclosure panels, help sections, and inline dialogs. The component state describes whether the content exists in the rendered output.

Hide With CSS When the Element Must Stay Mounted

Sometimes you do not want to unmount the element. Maybe it holds internal state, maybe you need a transition, or maybe layout measurement depends on it being present. In those cases, keep the element mounted and hide it with CSS.

jsx
1function Alert({ visible }) {
2  return (
3    <div style={{ display: visible ? "block" : "none" }}>
4      Build completed successfully.
5    </div>
6  );
7}

A class-based version is often cleaner:

jsx
1function Alert({ visible }) {
2  return (
3    <div className={visible ? "alert alert--visible" : "alert alert--hidden"}>
4      Build completed successfully.
5    </div>
6  );
7}
css
1.alert--hidden {
2  display: none;
3}
4
5.alert--visible {
6  display: block;
7}

This keeps the component mounted. Any internal React state stays alive, and effects do not re-run because of a full unmount and remount cycle.

Decide Based on Lifecycle and State

The practical rule is:

  • use conditional rendering if the UI should disappear completely
  • use CSS hiding if the UI should remain mounted

That difference matters more than people expect. If you unmount a component, you lose its local state and any effects get cleaned up. That is correct for many panels, but wrong for things like partially completed form steps or expensive embedded editors.

If preserving internal state is important, hiding is often the better option.

Accessibility Matters Too

Visibility changes should also be understandable to users with assistive technology. If a button expands or collapses a section, expose that state clearly.

jsx
1import { useId, useState } from "react";
2
3function Disclosure() {
4  const [open, setOpen] = useState(false);
5  const panelId = useId();
6
7  return (
8    <div>
9      <button
10        aria-expanded={open}
11        aria-controls={panelId}
12        onClick={() => setOpen((value) => !value)}
13      >
14        {open ? "Hide details" : "Show details"}
15      </button>
16
17      {open && <div id={panelId}>Extra information for the user.</div>}
18    </div>
19  );
20}

This makes the interaction clearer for screen readers and aligns the button text with the current state.

When Animation Changes the Choice

Animations are a common reason to keep content mounted. If a panel needs to fade or slide, removing it instantly from the tree can fight the animation. In those cases, developers often keep it mounted, toggle a class, and let CSS or an animation library handle the transition.

That is not just visual polish. It is also a lifecycle decision.

Common Pitfalls

One common mistake is hiding with CSS when the component should really unmount. That can leave timers, listeners, or heavy child components alive when they are no longer needed.

The opposite mistake is conditionally rendering a component whose local state should persist. If it disappears from the tree, that state is gone unless it has been lifted elsewhere.

Another issue is accessibility. A toggle button that changes visibility without clear labeling or aria-expanded leaves the interaction ambiguous for some users.

Finally, avoid using inline visibility logic everywhere by habit. Pick the rendering strategy that matches lifecycle needs, not just the shortest code.

Summary

  • In React, showing or hiding can mean conditional rendering or CSS-based hiding.
  • Conditional rendering removes the element from the DOM entirely.
  • CSS hiding keeps the element mounted and preserves component state.
  • State drives most visibility toggles, usually with useState.
  • Choose the approach based on lifecycle, state retention, animation, and accessibility requirements.

Course illustration
Course illustration

All Rights Reserved.