How to conditionally wrap JSX with a component in React
Nick Scialli
June 14, 2021
Sometimes we want to have content in React be wrapped in another component, and sometimes we don’t. In this post, we create a Wrapper
that either renders its children in a component or it doesn’t.
An example scenario
Let’s say we have some JSX that will either be shown in-app or, in another scenario, will be shown inside a modal. We have a Modal
component, but we’re not quite sure How to efficiently render the JSX inside it or not.
An initial approach
One approach could be to repeat the content, once inside the modal and once not inside the modal. Then, we use a ternary operator to show one version or the other:
function MyComponent(props) {
return (
<div>
<h1>Some content here</h1>
<p>Some other content</p>
{props.showModal ? (
<Modal>
<h2>Flexible content</h2>
<p>This is some content that may be in a modal or may not.</p>
</Modal>
) : (
<>
<h2>Flexible content</h2>
<p>This is some content that may be in a modal or may not.</p>
</>
)}
</div>
);
}
Of course, this is pretty ugly! We’re violating the Don’t Repeat Yourself (DRY) tenet of programming. One way we could make this a bit better is to store our repeated content in a variable:
function MyComponent(props) {
const content = (
<>
<h2>Flexible content</h2>
<p>This is some content that may be in a modal or may not.</p>
</>
);
return (
<div>
<h1>Some content here</h1>
<p>Some other content</p>
{props.showModal ? <Modal>{content}</Modal> : content}
</div>
);
}
This cleans it up quite a bit! But there’s another way that I think can make our code look cleaner and give us a lot more flexibility and reusability—creating a wrapper component that lets us render the content based on its props.
A wrapper component
Let’s create a wrapper component that takes showModal
as a prop. If that prop is truthy, we show the component’s children
in a modal. If not, we just return the children:
function Wrapper(props) {
if (props.showModal) {
return <Modal>{props.children}</Modal>;
}
return props.children;
}
Then, we can pull this into our other component like so:
function MyComponent(props) {
return (
<div>
<h1>Some content here</h1>
<p>Some other content</p>
<Wrapper showModal={props.showModal}>
<h2>Flexible content</h2>
<p>This is some content that may be in a modal or may not.</p>
</Wrapper>
</div>
);
}
I think this looks pretty clean. It gives us more options of what we can render inside the Wrapper
(perhaps we have more than two permutations). Also, Wrapper
is now reusable in case this is a patter throughout the application.
Nick Scialli is a senior UI engineer at Microsoft.