loading...
Cover image for React Hooks vs. Svelte

React Hooks vs. Svelte

jesseskinner profile image Jesse Skinner Originally published at codingwithjesse.com Updated on ・2 min read

I get asked a lot on my Twitch channel to show a comparison of React and Svelte. I thought I'd record a short video to show everyone how to take a basic React example and rewrite it using Svelte:

Let's look at a basic example from the React Hooks documentation. Here we have a simple component with a button, and some text showing you how many times you've clicked the button. We're using some state in our component, to keep track of how many times the button was clicked. It's a nice, simple example of using a stateful component:

import React, { useState } from 'react';

function Example() {
    // Declare a new state variable, which we'll call "count"
    const [count, setCount] = useState(0);

    return (
        <div>
            <p>You clicked {count} times</p>
            <button onClick={() => setCount(count + 1)}>Click me</button>
        </div>
    );
}

What would this look like written with Svelte? Turns out, most of the code above is React boilerplate that we can do without. Let's start by commenting out all the boilerplate:

// import React, { useState } from 'react';

// function Example() {
// Declare a new state variable, which we'll call "count"
const [count, setCount] = useState(0);

// return (
<div>
    <p>You clicked {count} times</p>
    <button onClick={() => setCount(count + 1)}>Click me</button>
</div>;
// );
// }

That gets us some of the way, but that's still not valid Svelte. Svelte is an extension of HTML, so we need to put our JavaScript code in a <script> block, and change it to use a local state variable instead of React's useState function:

<script>
    // Declare a new state variable, which we'll call "count"
    let count = 0;
</script>

<div>
    <p>You clicked {count} times</p>
    <button onClick={() => setCount(count + 1)}>Click me</button>
</div>

This is very close to Svelte, but we have to change one more thing. We need to change React's onClick attribute to Svelte's on:click, and then change the click handler so it simply increments count:

<script>
    // Declare a new state variable, which we'll call "count"
    let count = 0;
</script>

<div>
    <p>You clicked {count} times</p>
    <button on:click={() => count++}>Click me</button>
</div>

All done! When you change React code into Svelte code, you spend most of your time deleting code, and deleting code feels amazing!

The major difference here is that your state is kept in local JavaScript variables instead of being tied up inside useState. This means you can set your state variable to a new value without calling a function, and that makes it possible to keep your component code very clean and succinct.

In fact, if you came up to me and said you had a new framework that was even simpler than Svelte, I'd have a hard time believing it! I mean, what could we remove from that Svelte component? Even Vanilla JavaScript would be way more complicated than this basic Svelte example. Svelte makes our web components as simple as possible, but no simpler.


Interested in Svelte and web development? Subscribe to the Coding with Jesse newsletter!

Discussion

pic
Editor guide
Collapse
seanmclem profile image
Seanmclem

Where is the component named? In React it's the exported function name, but what about svelte?

Collapse
jesseskinner profile image
Jesse Skinner Author

Great question. In Svelte, you give a component a name when you import it. The whole file is the component, and it ends up being the default export. Typically you'd give the component file the same filename as the component name you want to be used. For example:

<script>
import Example from './Example.svelte';
</script>

<Example />
Collapse
seanmclem profile image
Seanmclem

Cool that makes sense. So definitely never two components in one file? I've been meaning to try svelte out lately. Just got to find a good project to test it with

Thread Thread
jesseskinner profile image
Jesse Skinner Author

Yes exactly, one component per file. It's an interesting design decision, but I think it's a smart one, because it really minimizes the boilerplate needed. In fact, an empty file is a valid Svelte component!

Thread Thread
seanmclem profile image
Seanmclem

Yeah usually the only reason why I end up putting two components in one file for react is to avoid having to write those few lines of boilerplate over again. If I don't have to do that then I would be able to stick to the best practice of using a new file for every one

Collapse
gpeto91 profile image
Gabriel Azevedo

Great article! I'm in love with Svelte, it makes me feel so productive. Recently I made one small project with Svelte and then with React. Just to see the difference. React has more (better) tools like routing, making UI... which is natural. But developing this project with Svelte was pretty straightforward and fluid. I'm not sure if Svelte is ready to be used in large, complex projects though. What do you think? Thanks!

Collapse
peceps profile image
Pece S.

I am also using it in production.
Development experience with Svelte has been great.
I am blown away by it.
We did not have any issues related to the framework.
There are some features that we've felt that we need but they are not available yet.
Performance has been great. Stability, predictability has been great.
Compile time barely noticeable.

Collapse
jesseskinner profile image
Jesse Skinner Author

Thanks! I think it's ready. I'm already using it in production. To avoid making a mess of spaghetti as complexity increases, I've been finding it helpful to keep Svelte components as small as possible, use Svelte stores heavily to deal with data loading or to share state between components, minimize the usage of reactive statements, and generally try to keep the amount of JavaScript in each component to a minimum. I plan to write these suggestions up in a longer post one day soon.

Collapse
gpeto91 profile image
Gabriel Azevedo

Looking forward to these suggestions! Right now I try to isolate my main .svelte file keeping only core structure there. Then I have an 'actions' folder and 'services' folder. Functions like fetchData() is inside services and listData() inside actions. So in my main .svelte I just call these actions. I think it's clean and easy to maintenance.

Example

Collapse
andregoldstein profile image
André Goldstein

Thanks for this. I think for simple comparisons Svelte always seems much simpler but React hooks allow for a large amount of code reuse across components. I've yet to see a similarly efficient way this can be done with Svelte

Collapse
jesseskinner profile image
Jesse Skinner Author

Do you have an example of the sort of reuse you can do in React that you can't do with Svelte?

Collapse
andregoldstein profile image
André Goldstein

Hi. It can be handy for quite a few things across an app. Implementing a data loading strategy and receiving error, loading, data props for example.

In Meteor I combine it with the name of a method

const { loading, error, data } = useMethod('fetchClients', { params })
Enter fullscreen mode Exit fullscreen mode

Or even simpler things like abstracting away certain functionalities like keeping a net, gross and tax rate in-sync

const { net, gross, taxRatio } = usePrice(2500)
Enter fullscreen mode Exit fullscreen mode

I'm sure there are better examples out there, just a few ideas off the top of my head. You also have the fact that as it's such a familiar pattern, you have libraries out there like github.com/streamich/react-use where you can drop in incredibly useful functionality and instantly know how to use it.

I'm not saying you can't achieve similar things with Svelte but I'm not sure if there are patterns that help abstract this stuff away as efficiently?

Thread Thread
jesseskinner profile image
Jesse Skinner Author

The way to do these things with Svelte is either to call functions from inside reactive statements, or to use stores, which can be written in regular JavaScript but use in a reactive way in your Svelte components.

Collapse
256hz profile image
Abe Dolinger

That's pretty compelling. I'll be in React Native land for a while, but maybe by then, there'll be a Svelte Native. Interested to see some more involved examples.

Collapse
jesseskinner profile image
Jesse Skinner Author

Great idea. I love rewriting React code as Svelte, I'd like to do a more complicated example in a future post or video sometime.

Collapse
thm_33 profile image
Thomas Valadez

What about helper functions like 'useContext' and 'useEffect' any tips on how to share state or reconcile complex prop updates or cleanup event listeners.

Collapse
jesseskinner profile image
Jesse Skinner Author

Sure, Svelte has a bunch of features that can help here. Stores, onMount, context, and event dispatching. svelte.dev/docs

Collapse
codelitically_incorrect profile image
Info Comment marked as low quality/non-constructive by the community. View code of conduct
codelitically_incorrect

People, really don't know JavaScript in 2019