You have an element that you would like to show or hide, for example an element that is shown or hidden when a user clicks a button. How do you conditionally render an element?
There are three common ways to conditionally render elements in JSX: using the logical AND (&&) operator, using the conditional (ternary) operator, and using an if
statement.
You can use the logical AND (&&) operator to conditionally render an element based on a boolean state value:
export default function MyComponent() { const [isOpen, setIsOpen] = useState(false); function toggle() { setIsOpen((isOpen) => !isOpen); } return ( <div className="App"> {isOpen && <Popup />} <button onClick={toggle}>Toggle show</button> </div> ); }
In the example code above, the component Popup
is initially not shown. When the “Toggle show” button is clicked once, isOpen
is set to true. MyComponent
re-renders and the component Popup
is rendered as a React element. If the button is clicked again, isOpen
is set to false and the Popup
component is not rendered.
The issue with using the &&
operator is that you may end up unintentionally rendering 0
instead of nothing if the value to the left of the &&
operator is 0
, which would be the case in the following code if the items
prop was an array with no items.
function ItemList({ items }) { return ( <div> <ul> {items.length && items.map((item) => <li key={item.id}>{item.name}</li>)} </ul> </div> ); }
The &&
operator evaluates the values it compares, the operands, from left to right. It returns immediately with the value of the first falsy value it finds. If all values are truthy, the last evaluated value is returned. This is why 0
would be displayed if the value of items.length
is 0. The length of []
is 0. You can fix this by making sure that the value is a boolean, for example:
!!items.length && ... // or items.length > 0 && ... // or Boolean(items.length) && ...
You can use a ternary operator to conditionally render an element without having to worry about converting values to booleans:
function ItemList({ items }) { return ( <div> <ul> {items.length ? items.map((item) => <li key={item.id}>{item.name}</li>) : null} </ul> </div> ); }
if
statementYou can also use an if
statement instead of a ternary operator if you prefer the syntax:
function ItemList({ items }) { let itemsElements = null; if (items.length) { itemsElements = items.map((item) => <li key={item.id}>{item.name}</li>); } return ( <div> <ul>{itemsElements}</ul> </div> ); }