design tools

Conditional Rendering

Conditional rendering is the React technique that uses JavaScript logic directly in JSX to show, hide or swap UI components based on conditions. It turns every state your design system supports into code that the browser can understand. The three primary shapes are ternaries that choose between two options, short circuit ANDs that add optional elements, and early returns that replace the entire component with something completely different. Designers treat these as the code version of Figma variants and states. Read them first in any TSX file after you check the props and you immediately see the decision tree that drives the interface at companies like Vercel, Linear, and Stripe in 2026. The pattern reveals exactly which states the engineer thought were important. If your Figma file has an error state but the code has no conditional for it you just found a bug before it shipped to users.

This pattern lives at the heart of modern frontend work because interfaces are never static. They respond to data loading, user permissions, network failures, and business logic. Without solid conditional rendering your polished success state sits next to an undrawn blank screen when something goes wrong in production. The logic does not need to be complex. A single prop like status equals loading triggers the right piece of UI from a set of pre designed options. The skill for designers is recognizing these patterns without needing to write the code themselves. The parent article on reading code without coding lays out the exact scan order. Find the conditions right after you map the props and variants. Ignore the useState and useEffect blocks. They are engineering territory. The conditionals are design territory.

Conditional rendering is not styling. It is not the Tailwind classes that adjust padding or color based on a prop. Those belong in the variant definitions using objects that map strings to class names. It is not the data fetching logic or the useState hooks that manage the variables used in the conditions. Skip those lines entirely and focus on the return statement where the actual UI tree lives. It is also not an excuse to create twenty different states that should have been consolidated into three clean ones. Overuse creates brittle components that break when one condition changes. True conditional rendering stays crisp. It controls large distinct sections of the UI like entire panels or messages not fine grained style tweaks that should be handled with variants.

It is definitely not the same as CSS media queries or hover states handled by group hover in Tailwind. Those are responsive design and interaction details handled in stylesheets or Framer Motion prototypes. Conditional rendering operates at the component level. It decides whether a chunk of the DOM exists at all based on JavaScript values. Confusing the two leads to code that mixes concerns and becomes impossible to maintain by either designers or engineers. Designers who understand the boundary leave better PR comments. They say add a designed illustration to this error conditional instead of trying to patch the logic themselves and risking a regression in the payment flow.

Here is a concrete example pulled from the Notion workspace switcher in late 2025. The component file starts with an early return. If the user object is null it returns a full screen SignInPrompt that includes the updated Notion logo, a custom illustration of a locked door, supportive copy written by their content team, and a primary button that matches the brand color exactly. Once the user loads the code hits a ternary for the loading state that looks like this. isLoading ? <WorkspaceSkeleton rows={3} /> : <WorkspaceList />. The skeleton uses gray blocks with the exact same border radius and line heights as the real content so the layout shift is zero. Inside the list another conditional checks for zero workspaces and short circuits an EmptyState component. That empty state includes a specific illustration of an empty folder with a plant growing from it, the text Create your first workspace, and a button with the precise padding and typography from the design system. The designer reviewing this PR opened the file in Cursor and used the prompt to list every conditional render and the design state each one represents. The AI output showed a mismatch in the empty state illustration size. One targeted comment fixed it in the next commit.

Stripe Checkout in 2026 uses even more conditionals in their payment form component. The card element renders a different footer based on whether the payment is processing with the short circuit pattern. It uses isProcessing && <ProcessingSpinner message="Completing secure checkout" />. The spinner matches the brand animation guidelines from their 2026 design system refresh. For errors it deploys a full width banner with red accent color from the palette, the exact copy approved by legal, and a retry button. The early return at the top of the file handles the success state by showing a full page takeover with confetti animation component using green brand colors, receipt details pulled from the API, and a button to return to the merchant site. Each of these was designed as a separate variant in Figma complete with specific typography scales from their token set, spacing using the 4px grid, and microcopy. The design team caught three mismatches in the first PR by scanning for the question marks and logical operators in the JSX. They used the Claude Code prompt from the reading code guide to sweep for every conditional and map it to a state. The result was zero surprises when the feature reached production users at thousands of internet businesses.

Another example comes from Figma own config panel for auto layout features in 2026. The panel shows different controls based on the selected node type using a large ternary operator at the top level of the returned JSX. One branch shows padding inputs with labels and sliders. The other branch shows corner radius controls with presets. The short circuit pattern adds a warning banner only when the user has selected items that cannot use the feature like a group with mixed types. The banner uses the yellow color from the Figma 2026 palette and includes a link to the documentation. These patterns let the design team own the states without touching the React code. They simply verify the logic surfaces every state they drew in their component library file. The same approach appears in the Cursor AI code editor itself where the suggestion panel uses conditionals to switch between inline preview, loading dots with branded animation, error recovery options with specific retry UI, and the empty state when no suggestions are available. Each state was designed in Figma first then verified in the TSX file.

Use conditional rendering when you need to handle distinct modes of the same interface component. Apply it liberally for loading states with skeleton components, error states with actionable messages, empty states with helpful illustrations, success states with celebratory feedback, and permission based views that gate features for different user roles. Always pair it with a complete set of Figma states so nothing gets missed in the handoff. The pattern becomes dangerous when it grows too large or nested. If your ternary contains another ternary that contains yet another you have left the design surface and entered spaghetti territory. Split the component into smaller focused pieces instead. Do not use conditionals for data transformation or complex calculations. Keep those outside the return block where engineers can own them without designer input. The best teams treat every conditional as a contract with design. The code must match the states or the PR does not merge. This approach works especially well in Tailwind codebases where the visual changes are easy to scan because the class names sit right next to the conditional logic in the file.

Avoid conditionals for anything that can be handled with CSS or variant props. Hover states, focus rings, and disabled styles belong in the base button variants not in logic blocks. Do not let them control layout primitives like switching from flex to grid based on screen size. Those changes often signal the need for two separate components or a responsive layout primitive rather than one giant conditional monster that is hard to test. When the logic depends on more than two or three states consider a switch statement mapped to components or a lookup object that selects the right one by key. This keeps the JSX clean and readable for the entire product team including the designers who review it every sprint.

Designers who master this pattern stop fearing the codebase and start contributing at a deeper level. They open a TSX file, run the five glance scan from the reading code playbook, and immediately see the states that need attention or are completely missing. The conditional lines jump out like red lines in a Figma comment thread because they know exactly what to look for. They become the bridge between the design file and the production app. In 2026 that skill separates teams that ship pixel perfect experiences from those that ship close enough and then spend weeks patching bugs. The checklist at the end of the parent article includes a specific line for this pattern. Every conditional render maps to a designed state. Run that check on every frontend PR and watch the quality of shipped interfaces improve overnight at your own company.

Conditional rendering turns every question mark in a TSX file into a designed state that ships exactly as drawn.

Related terms

Keep exploring