Logo

dev-resources.site

for different kinds of informations.

When Goliath Fell to David’s Smallest Stone: The Innocent Dropdown Tweak That Shattered React, Vue, and Svelte

Published at
12/18/2024
Categories
react
vue
svelte
webdev
Author
ryo_suwito
Categories
4 categories in total
react
open
vue
open
svelte
open
webdev
open
Author
10 person written this
ryo_suwito
open
When Goliath Fell to David’s Smallest Stone: The Innocent Dropdown Tweak That Shattered React, Vue, and Svelte

Once Upon a Time, Chaos Reigned in Front-End Development

The front-end world has been ruled by frameworks that promised you freedom:

  • React, the "build anything, but at what cost?" framework.
  • Vue, the "everything is kinda okay but just try to reuse your logic, I dare you" framework.
  • Svelte, the "we’re simple until you need inheritance, then good luck" framework.

For years, developers convinced themselves these tools were the pinnacle of modern engineering. But behind the promises of "flexibility" and "developer experience" lurked frustration, duplication, and tears.


The Challenge: A Button with a Dropdown

Let’s test these frameworks—and Neuer—on a simple task:

A button with a dropdown.

The Use Cases:

  1. Version 1: Create a button with a dropdown.
  2. Version 2: Customize the dropdown’s content.
  3. Version 3: Override the click behavior.
  4. Version 4: Change styles to match a new context.

Sounds easy, right? Watch the big three fall apart. 🎭


React: A Render Function and a Prayer

React devs, gather ‘round. Here’s your React-based dropdown:

const DropdownButton = () => {
  const [open, setOpen] = React.useState(false);
  return (
    <div className="dropdown">
      <button className="btn" onClick={() => setOpen(!open)}>
        Click Me <span className="caret"></span>
      </button>
      <div className={`dropdown-content ${open ? "show" : ""}`}>
        Dropdown content
      </div>
    </div>
  );
};
Enter fullscreen mode Exit fullscreen mode

At first glance:

"Wow, React is so clean! Look at that JSX!"

But now let’s tweak it.


Version 2: Customize Dropdown Content

React says: "Time to rewrite everything!"

const CustomDropdownButton = () => {
  const [open, setOpen] = React.useState(false);
  return (
    <div className="dropdown">
      <button className="btn" onClick={() => setOpen(!open)}>
        Click Me <span className="caret"></span>
      </button>
      <div className={`dropdown-content custom-style`}>
        Totally custom content!
      </div>
    </div>
  );
};
Enter fullscreen mode Exit fullscreen mode

Duplicated logic, duplicated state.

Hope you remembered to copy the setOpen function, or you’ll break everything. 🙃


Version 3: Override the Click Behavior

React says: "Sure, but you’ll need to rewrite the whole component again."

const CustomClickDropdown = () => {
  const [open, setOpen] = React.useState(false);
  const customToggle = () => console.log("Custom click logic!");
  return (
    <div className="dropdown">
      <button className="btn" onClick={customToggle}>
        Click Me <span className="caret"></span>
      </button>
      <div className={`dropdown-content ${open ? "show" : ""}`}>Dropdown content</div>
    </div>
  );
};
Enter fullscreen mode Exit fullscreen mode

Fun Fact: That setOpen logic? Yeah, it’s gone now. Good luck handling state without rewriting it all. 😏


Version 4: Change Styles

React says: "Hope you enjoy inline styles or CSS modules!"

const StyledDropdownButton = () => {
  const [open, setOpen] = React.useState(false);
  return (
    <div className="dropdown" style={{ backgroundColor: "lightblue" }}>
      <button className="btn" onClick={() => setOpen(!open)}>
        Click Me <span className="caret"></span>
      </button>
      <div className={`dropdown-content ${open ? "show" : ""}`}>Dropdown content</div>
    </div>
  );
};
Enter fullscreen mode Exit fullscreen mode

Inline styles? Really? Are we in 2013? React: where modularity goes to die. 💀


Vue: Directives All Day, Every Day

Here’s Vue’s starting dropdown:

<template>
  <div class="dropdown">
    <button class="btn" @click="toggleDropdown">
      Click Me <span class="caret"></span>
    </button>
    <div :class="['dropdown-content', { show: isOpen }]">Dropdown content</div>
  </div>
</template>

<script>
export default {
  data() {
    return { isOpen: false };
  },
  methods: {
    toggleDropdown() {
      this.isOpen = !this.isOpen;
    },
  },
};
</script>
Enter fullscreen mode Exit fullscreen mode

Looks nice! But let’s see the cracks.


Version 2: Customize Dropdown Content

Vue says: "Go ahead and duplicate everything."

<template>
  <div class="dropdown">
    <button class="btn" @click="toggleDropdown">
      Click Me <span class="caret"></span>
    </button>
    <div class="dropdown-content custom-style">Totally custom content!</div>
  </div>
</template>

<script>
export default {
  data() {
    return { isOpen: false };
  },
  methods: {
    toggleDropdown() {
      this.isOpen = !this.isOpen;
    },
  },
};
</script>
Enter fullscreen mode Exit fullscreen mode

Another entire component for one small tweak. DRY? What’s that? 🥴


Version 3: Override the Click Behavior

Vue says: "Rewrite the methods section too, kid."

<script>
export default {
  data() {
    return { isOpen: false };
  },
  methods: {
    toggleDropdown() {
      console.log("Custom click logic!");
    },
  },
};
</script>
Enter fullscreen mode Exit fullscreen mode

Your dropdown’s behavior is isolated from the base logic. Hope you don’t need to share any logic with other components.


Version 4: Change Styles

Vue says: "Scoped styles to the rescue!"

But you still need to copy the template and styles into a new file.


Svelte: Rewrite It All, Forever

In Svelte, you get simplicity… until you need to reuse or tweak something.


The Neuer Way: One Class to Rule Them All

Version 2: Customize Dropdown Content

Extend. Override get template. Done.

export class CustomDropdown extends DropdownButton {
    static {
        this.registerElement();
    }
    get template() {
        return `
            <div class="dropdown">
                <button class="btn" c-click="toggleDropdown">Click Me <span class="caret"></span></button>
                <div class="dropdown-content custom-style">Totally custom!</div>
            </div>
        `;
    }
}
Enter fullscreen mode Exit fullscreen mode

Version 3: Override Click Behavior

Override one method. Done.

export class CustomClickDropdown extends DropdownButton {
    static {
        this.registerElement();
    }
    toggleDropdown() {
        console.log("Custom click logic!");
    }
}
Enter fullscreen mode Exit fullscreen mode

Version 4: Change Styles

Tweak get styles. Done.

export class StyledDropdown extends DropdownButton {
    static {
        this.registerElement();
    }
    get styles() {
        return `
            ${super.styles}
            .dropdown-content {
                background-color: lightblue;
                color: darkblue;
            }
        `;
    }
}
Enter fullscreen mode Exit fullscreen mode

The Moral of the Story

React makes you duplicate.

Vue makes you rewrite.

Svelte makes you start over.

Neuer? Makes you smile. 😏

Stop copying, pasting, and rewriting your life away. It’s time for a Neuer way of doing things.

Welcome to the future.

svelte Article's
30 articles in total
Favicon
🚀 I have released Eurlexa!!! EU Regulation at Your Fingertips!
Favicon
Building "Digital DSA": The Journey of Crafting a Smarter Loan Comparison Platform
Favicon
Tower defense clicker game built with Svelte 5, without canvas. Only CSS transitions and the power of Runes
Favicon
Optimize SvelteKit performance with brotli compression
Favicon
Migrating the VSCode theme generator to oklch
Favicon
Beatbump: Exploring Svelte Best Practices for Dynamic Web Applications
Favicon
SvelteJs vs ReactJs : But both can co-exists!
Favicon
Build a Simple Chatbot with Svelte and ElizaBot
Favicon
A minimalist password manager desktop app: a foray into Golang's Wails framework (Part 2)
Favicon
The Perfect Trio: Wails, Go & Svelte in Action
Favicon
Svelte 5: Share state between components (for Dummies)
Favicon
Integrating SvelteKit with Storyblok (Using Svelte 5)
Favicon
Changelog 2024/48 aka We 🖤 Svelte 5
Favicon
My first Micro SaaS | Automated, SEO-friendly Changelogs
Favicon
Quit Using Anonymous Functions in Props!
Favicon
From Svelte 4 to Svelte 5: Understanding Slots (default and named)
Favicon
Make EditorJS work in Svelte(kit) SSR
Favicon
Shadcn UI Theme generator, with OKLCH colors and ancient sacred geometry.
Favicon
A short guide to Async Components in Svelte 5
Favicon
New Post here!🍻
Favicon
Svelte vs Vue: Choosing the Best Front-End Framework
Favicon
Step-by-Step Tutorial: How to Use ALLAIS for Effortless UI Generation
Favicon
Schritt-für-Schritt-Anleitung: So verwenden Sie ALLAIS für die einfache UI-Generierung
Favicon
ALLAIS: Your Ultimate Personal UI Generator for Modern Web Development
Favicon
Пошаговый учебник: Как использовать ALLAIS для легкой генерации UI
Favicon
Svelte
Favicon
A minimalist password manager desktop app: a foray into Golang's Wails framework (Part 1)
Favicon
When Goliath Fell to David’s Smallest Stone: The Innocent Dropdown Tweak That Shattered React, Vue, and Svelte
Favicon
Deploying Your SvelteKit App to GitHub Pages with a Custom Domain (Ditch GoDaddy for Porkbun)
Favicon
Syncing DOM State and Data without IDs

Featured ones: