DEV Community

Cover image for Svelte for React dev
Alexey Lysenko
Alexey Lysenko

Posted on

Svelte for React dev

My main frontend framework is React, I use them in all my commercial project by default. It is some word, the best technology for the project is that you know, but sometimes we need to expand our experience and knowledge. For me, the best way to do this is to try new tech on my personal projects. And this is shine time for Svelte!

The project that I built is to track what booby you feed the baby last time. So my wife can click on a bubble, and add time and category to the list. You can see it deployed here
https://boobs-app.vercel.app/
and also you can take a look full code here:
https://github.com/detoner777/boobs-app

To initialize the svelte project, I use the REPL https://svelte.dev/blog/the-easiest-way-to-get-started
and ready to go.

Svelte is a component-based framework like the most modern popular ones. So if you are familiar with React you will without a problem handle Svelte. Let's take a look first at the project structure:

Screenshot_1

In the src directory, I have App.svelte this is our root svelte file. And main.js, this is the file has a code:

import App from "./App.svelte";

const app = new App({
  target: document.body,
});

export default app;
Enter fullscreen mode Exit fullscreen mode

and used by rollup for bundling app.

In the component folder is two files which have .svelte

Screenshot_2
This is how we define Svelte components.

In the Item.svelte component that looks like this:

<script>
  export let time;
  export let boob;
  export let index;
</script>

<style>
  .item {
    font-size: 20px;
    padding: 0.5rem;
    border: 1px solid #03e2fc;
    border-width: 0 0 1px;
    width: 60%;
    margin: 0 auto;
    transition: all 0.3s;
  }
  .active {
    background: rgba(255, 255, 255, 0.1);
    border-width: 0.1px 0;
    transform: scale(1.3);
    margin-bottom: 0.5rem;
    transition: all 0.3s;
  }
</style>

<div class={`item ${index === 0 && 'active'}`}>
  <span>{time}</span>
  <span>{boob}</span>
</div>
Enter fullscreen mode Exit fullscreen mode

it has 3 main sections:

<script>
all js file writs here
</script>
Enter fullscreen mode Exit fullscreen mode

css

<style>
  .item {
    font-size: 20px;
    padding: 0.5rem;
    ...
  }
</style>
Enter fullscreen mode Exit fullscreen mode

and layout:

<div>
  <span></span>
  <span></span>
</div>
Enter fullscreen mode Exit fullscreen mode

In this structure App.svelte components parent for child Boobs.svelte and Item.svelte. Like in React we can pass propse from parent to child. In the App :

 <Item time={event.time} boob={event.boob} {index} />
Enter fullscreen mode Exit fullscreen mode

{index} index value that passed itself. So it's the cool syntax in this case.
In the Item:

<script>
  export let time;
  export let boob;
  export let index;
</script>
Enter fullscreen mode Exit fullscreen mode

Exporting values passed as props to our component.

Svelte based on a "true" reactivity for keeping the DOM in sync with your application state. It mins that you don't need to setState if need to update value, but directly assign new value

in React:

const [count, setCount] = useState(0);

function increment() {
  setCount(count + 1);
}
Enter fullscreen mode Exit fullscreen mode

same in Svelte:

let count = 0;

function increment() {
  count += 1;
}
Enter fullscreen mode Exit fullscreen mode

it youse the same concept but less code to write.

In React, we often use pattern map() to loop over components to render multiple lists and if/else block for conditional rendering. In the Svelte this pattern has a special syntax, intuitive for React developers

 <div class="item-container">
    {#if JSON.parse($events)?.length > 0}
      {#each JSON.parse($events).reverse() as event, index   (event.id)}
         <Item time={event.time} boob={event.boob} {index} />
      {/each}
    {/if}
  </div>
Enter fullscreen mode Exit fullscreen mode

The expression JSON.parse($events).reverse() array but it can be array-like object (i.e. it has a length property). You can loop over generic iterables with each [...iterable].

This is a basic meeting with this technology. Svelte has very detailed and comfortably to use documentation https://svelte.dev/. As a developer personally I don't know when I use this on a real commercial project, but definitely, I will be using him on small apps.

Top comments (3)

Collapse
 
pengeszikra profile image
Peter Vivo
let count = 0;

function increment() {
  count += 1;
}
Enter fullscreen mode Exit fullscreen mode

In my read: increment function have outer dependency, so this is impure solution.

Collapse
 
fkrasnowski profile image
Franciszek Krasnowski

So is the React one:

function increment() {
  setCount(count + 1);
}
Enter fullscreen mode Exit fullscreen mode

Both setCount and count are outer dependencies. You can do:

function increment() {
  setCount(count => count + 1);
}
Enter fullscreen mode Exit fullscreen mode

But still, hooks are impure by definition. They make components stateful and therefore impure. Svelte takes advantage of being a compiler and instead of writing custom hooks, which are impure. You can use a couple of approaches to make your state more predictable. Like stores:

const count = writable(0)
const increment = () => count.update(count => count + 1)
Enter fullscreen mode Exit fullscreen mode

Where the writable is a regular framework-agnostic store not necessarily bounded to component context, thus you can test it without additional dependencies, hook runners, etc. For example, Svelte spring transitions are handled by stores, not in custom hooks like in react-spring or framer-motion. But in my opinion, the true advantage of Svelte approach is that state mutations are just very terse and "explicit" in Svelte. In React the combination of multiple refs and useEffects sometimes causing me an eyestrain

Collapse
 
andrewbaisden profile image
Andrew Baisden

Keep hearing a lot about Svelte and how it is possibly the easiest javascript framework to learn.