Swizec Teller - a geek with a hatswizec.com

    Variants – a quick tip for better React components

    Say you're building a component that shows up in lots of places, like a header.

    Look at designs and sure enough, same header on every page. Logo, few buttons, username. You create a reusable component. DRY all the way.

    const Header = () => {
    return (
    <Box>
    <Logo />
    <MenuItem />
    <MenuItem />
    <UserMessages />
    <UserProfile />
    </Box>
    )
    }

    Fantastic! You have a header that works everywhere.

    A new page appears

    "Hey, header looks weird on homepage. Where's the signup button?"

    Your designer's not happy. Header that's the same everywhere can't be same on the homepage. That's for marketing, they need signups.

    obviously 🙄

    You add a prop.

    const Header = (props: { showSignup: boolean }) => {
    return (
    <Box>
    <Logo />
    <MenuItem />
    <MenuItem />
    {!props.showSignup && <UserMessages />}
    {!props.showSignup && <UserProfile />}
    {props.showSignup && <SignupButton />}
    </Box>
    )
    }

    Cool, you've kept it DRY. Same header, same styling, signup yes or no.

    A funnel shows up

    "Hey, users are getting distracted out of this purchase funnel. Header too busy"

    Your universal header is costing you money. When users are on the path to paying, you want nothing to stand in their way.

    Another boolean!

    "Oh and let's pretend this is a fullscreen modal, add a close button. Keep the logo"

    Two booleans!

    aqV7k1png2f49bb

    const Header = (props: {
    showSignup: boolean
    hideMenu: boolean
    showClose: boolean
    }) => {
    return (
    <Box>
    <Logo />
    {!props.hideMenu && <MenuItem />}
    {!props.hideMenu && <MenuItem />}
    {!props.showSignup && <UserMessages />}
    {!props.showSignup && <UserProfile />}
    {props.showSignup && <SignupButton />}
    {props.showClose && <CloseButton />}
    </Box>
    )
    }

    Well that's not confusing at all. With 3 booleans, your header has 8 possible incantations.

    Possible incantations of Header component
    Possible incantations of Header component

    Add one more ask from design and you're up to 16.

    😅

    You've created a mess

    Your beautiful universal header component is hard to use. Complexity is exploding, the code is getting hairy, and you're the only person on your team who knows how to hold it.

    For everyone else it's frustrating as heck. Get it right for this screen, breaks on that screen.

    Debugging feels like whack-a-mole.

    And I'm showing you a simple example. In production code these booleans start interacting. If hideMenu and showSignup then do X, otherwise if not showClose do Y.

    Nobody wants to touch your component ever again. It's too tricky.

    Variants to the rescue

    How many of those 8 incantations are valid?

    I count 3.

    Identify your variants
    Identify your variants

    Then why allow the other 5? If 5 out of 8 ways to use your component are bugs, something's wrong.

    Here's what you do 👉 turn those flags into a variant prop. Use TypeScript and you even get autocomplete 😍

    const Header = (props: { variant: "homepage" | "funnel" }) => {
    let hideMenu, showClose, showSignup
    switch (variant) {
    case "homepage":
    showSignup = true
    case "funnel":
    hideMenu = true
    showClose = true
    }
    return (
    <Box>
    <Logo />
    {!hideMenu && <MenuItem />}
    {!hideMenu && <MenuItem />}
    {!showSignup && <UserMessages />}
    {!showSignup && <UserProfile />}
    {showSignup && <SignupButton />}
    {showClose && <CloseButton />}
    </Box>
    )
    }

    Now the rest of your team can use your header with ease: <Header variant="..." />. And thanks to TypeScript their IDE tells them what's available.

    AND we found a bug in my pseudocode. You don't want user menus showing up in funnel headers 😅

    Cheers,
    ~Swizec

    PS: quick tip for shorter emails 👉 break your wrist

    Swizec Teller published SeniorMindset.com avatarSwizec Teller published SeniorMindset.com@Swizec
    And then I broke my wrist a little 😅
    Tweet media

    Did you enjoy this article?

    Published on March 2nd, 2021 in Technical, React, Lessons,

    Learned something new?
    Read more Software Engineering Lessons from Production

    I write articles with real insight into the career and skills of a modern software engineer. "Raw and honest from the heart!" as one reader described them. Fueled by lessons learned over 20 years of building production code for side-projects, small businesses, and hyper growth startups. Both successful and not.

    Subscribe below 👇

    Software Engineering Lessons from Production

    Join Swizec's Newsletter and get insightful emails 💌 on mindsets, tactics, and technical skills for your career. Real lessons from building production software. No bullshit.

    "Man, love your simple writing! Yours is the only newsletter I open and only blog that I give a fuck to read & scroll till the end. And wow always take away lessons with me. Inspiring! And very relatable. 👌"

    ~ Ashish Kumar

    Join 15,883+ engineers learning lessons from my "raw and honest from the heart" emails.

    ⭐️⭐️⭐️⭐️✨
    4.5 stars average rating

    Have a burning question that you think I can answer? Hit me up on twitter and I'll do my best.

    Who am I and who do I help? I'm Swizec Teller and I turn coders into engineers with "Raw and honest from the heart!" writing. No bullshit. Real insights into the career and skills of a modern software engineer.

    Want to become a true senior engineer? Take ownership, have autonomy, and be a force multiplier on your team. The Senior Engineer Mindset ebook can help 👉 swizec.com/senior-mindset. These are the shifts in mindset that unlocked my career.

    Curious about Serverless and the modern backend? Check out Serverless Handbook, for frontend engineers 👉 ServerlessHandbook.dev

    Want to Stop copy pasting D3 examples and create data visualizations of your own? Learn how to build scalable dataviz React components your whole team can understand with React for Data Visualization

    Want to get my best emails on JavaScript, React, Serverless, Fullstack Web, or Indie Hacking? Check out swizec.com/collections

    Want to brush up on modern JavaScript syntax? Check out my interactive cheatsheet: es6cheatsheet.com

    Did someone amazing share this letter with you? Wonderful! You can sign up for my weekly letters for software engineers on their path to greatness, here: swizec.com/blog

    Want to brush up on your modern JavaScript syntax? Check out my interactive cheatsheet: es6cheatsheet.com

    By the way, just in case no one has told you it yet today: I love and appreciate you for who you are ❤️

    Created by Swizec with ❤️