How to move around blocks of code with React and Tailwind
By Flavio Copes
Learn how to move a React component to a different place depending on screen size, using Tailwind responsive classes like hidden xl:block to show it twice.
To show a React component in a different place depending on the screen size, you can render it twice in the markup and use Tailwind responsive classes to make only one copy visible at a time. Let me show you how I got there.
While working on a Next.js website I had the need to move a React component to a whole different place in my markup, depending on the size of the screen.
In particular I had a Sidebar component I wanted on the left side of the screen on a big display, but before the content on a smaller display.
Due to the way I organized the HTML markup and the CSS, it was not immediately clear to me how to perform this transition without rewriting a good portion of it.
So I looked at Tailwind to provide me a nice solution.
And this was the way: I added the component twice on the screen, assigning the class hidden xl:block to the “big screen” part, and xl:hidden to the snippet for the smaller screens:
<div className="hidden xl:block">
<Sidebar />
</div>
...
<div className="xl:hidden">
<Sidebar />
</div>
How the classes work
Tailwind is mobile-first. A class without a prefix applies to every screen size, and a prefixed class like xl:block kicks in from that breakpoint up. By default xl means a viewport 1280px wide or more.
So the first wrapper is display: none on small screens, and becomes display: block on big screens. The second wrapper does the opposite: visible by default, hidden from xl up.
At any given screen size, the visitor sees exactly one Sidebar. You pick where each copy sits in the markup, so the component can live in completely different places in the layout.
The drawback
The component is rendered twice. Both copies exist in the DOM, React renders both, and CSS just hides one of them.
For my Sidebar, a presentational component without logic, that was a compromise I could live with.
Be careful when the component holds state or does work. Two copies means two independent states: if the sidebar had a search field, text typed on mobile would not appear in the desktop copy. And if the component fetches data in an effect, you’d fetch twice.
The fix for the state problem is to lift the state up: keep it in the parent and pass it down as props, so both copies read from the same source.
One more thing to check: if the component renders elements with an id attribute, you now have duplicate ids on the page, which is invalid HTML and can break labels and anchor links. Drop the ids or make them unique per copy.
For a stateless, presentational component, none of this bites you, and the trick is a one-minute change.