Svelte:

the React killer

(?)

Milano Front-End

June 25, 2019

JavaScript and Python trainer 

Valentino Gagliardi

I help people learning to code with remote and on-site workshops.

I write on my blog about JavaScript, Python, and Django.

It's that time again ...

  • Svelte 3 core concepts
  • Reactivity
  • Conclusions and resources

The plan

Goal of this talk

  • give you an overview of Svelte
  • compare Svelte to other libraries
  • spur an healthy discussion

1. The basics

Svelte is a library compiler ...

What is Svelte?

Borrows from React and Vue but it's quite unique.

Getting started

# create a new Svelte project
npx degit sveltejs/template links-app

# move into the project
cd links-app

# install deps and start the dev server
npm i

npm run dev

Svelte components

<!-- has .svelte extension -->

<script>
    let text = 'Default text'
</script>

<h1>{text}</h1>

Using components

<!-- Root component, App.svelte -->

<script>
    import H1 from './common/H1.svelte'
</script>

<H1/>

Declaring props


<script>
    // export makes "text" a prop
    export let text = 'Default text'
</script>

<h1>{text}</h1>

Passing props


<script>
    import H1 from './common/H1.svelte'
</script>

<H1 text="Passing some text"/>

Props as variables


<script>
    import H1 from './common/H1.svelte'
    let text = "Passing some text";
</script>

<H1 text={text}/>

Prop shorthand


<script>
    import H1 from './common/H1.svelte'
    let text = "Passing some text";
</script>

<H1 {text}/>

Spreading props

<script>
  // import your components here
  function handleChange() {
    console.log(`Do stuff!`);
  }
  const props = {
    id: "number",
    required: true,
    handleChange: handleChange
  };
</script>

<Form>
  <Input {...props} />
</Form>

Styling components

<script>
    export let text = 'Default text'
</script>

<style> 
    /* scoped by default */
    h1 {
    color: blueviolet;
    }
</style>

<h1>{text}</h1>

Child components in React are passed through the "children" prop.

Child components

In Svelte we refer to children as slot. (Vue has the same concept).

Children in React

import React from "react";

function Form(props) {
  return <form onSubmit={props.onSubmit}>
        {props.children}
        </form>;
};

<Form onSubmit={handleSubmit}>
    <Input/>
    <Button/>
</Form>

Children in Svelte


<script>
    // some js
</script>

<form>
    <slot/>
</form>

Children in Svelte


<script>
    // import some other component if needed
    import Form from './common/Form.svelte'
</script>

<Form>
    <input type="text" placeholder="Your name">
    <input type="email" placeholder="tom@jones.com">
</Form>

2. Forms and events

Events in Svelte


<script>
    function handleSubmit(event){
        const { elements } = event.target;
        // do stuff with the elements
    }
</script>

<form on:submit={handleSubmit}>
    <slot/>
</form>
  • preventDefault
  • stopPropagation
  • once: runs the handler only once

Event modifiers

Events modifiers


<script>
    function handleSubmit(event){
        const { elements } = event.target;
        // do stuff with the elements
    }
</script>
<form on:submit={handleSubmit}>
    <slot/>
</form>
<form on:submit|preventDefault={handleSubmit}>
    <slot/>
</form>

Controlled inputs

<script>
  export let required;
  // other props
  let searchTerm = "";
</script>

<input
  bind:value={searchTerm}
  type="search"
  {required} />

3. Reactivity

Why reactive?

More often than not your components need some computed value or derived state.

In Vue for example there is a computed property.

Computed in Vue

var vm = new Vue({
  el: '#example',
  data: {
    message: 'Hello'
  },
  computed: {
    reversedMessage: function () {
      return this.message.split('').reverse().join('')
    }
  }
})

Reactive declarations

<script>
  // import your components here
  let number = 0;
  function handleInputChange(event) {
    number = event.target.value;
  }
</script>

<Form>
  <Input id="number" handleChange={handleInputChange} />
  <!-- can I do better? -->
  <p>{number} multiplied by 2 is {number * 2}</p>
</Form>

<script>
  // import your components here
  let number = 0;
  // reactive declaration!
  $: multiplied = number * 2;
  function handleInputChange(event) {
    number = event.target.value;
  }
</script>

<Form>
  <Input id="number" handleChange={handleInputChange} />
  <p>{number} multiplied by 2 is {multiplied}</p>
</Form>

<script>
  // import your components here
  let number = 0;
  // will it work? (Spoiler: no)
  const multiplied = number * 2;
  function handleInputChange(event) {
    number = event.target.value;
  }
</script>

<Form>
  <Input id="number" handleChange={handleInputChange} />
  <p>{number} multiplied by 2 is {multiplied}</p>
</Form>

4. Fetching and rendering data

Fetching data

In React "there was" the good 'ol componentDidMount. In the hook era we have useEffect.

Svelte borrows from "classic" React with an onMount function.

Fetching data

<script>
  import { onMount } from "svelte";

  export let url = "";

  let data = [];

  onMount(async function getData() {
    const response = await fetch(url);
    data = await response.json();
  });
</script>

Lists in React

  const listItems = numbers.map((number) =>
    <li key={number.toString()}>
      {number}
    </li>
  );

React uses JSX which does not allow JavaScript statements except map and ternaries.

Lists in Svelte


<ul>
  {#each data as element}
    <li>
      <a href={element.url}>{element.title}</a>
    </li>
  {/each}
</ul>

Svelte has its conventions too, like the each block for rendering lists.

5. Wrapping up

Other goodies

  • out of the box SSR
  • built-in transitions
  • built-in state management

So why Svelte 3?

  1. Svelte is not a dependency
  2. it surgically compiles to vanilla JS
  3. no virtual DOM

Why NOT Svelte 3?

  1. the ecosystem is still immature
  2. "I don't want to rewrite everything again"
  3. There's too much React out there

BUT REMEMBER ...

JavaScript is brutal

Rule them all

Always keep learning the web platform and you will be able to master any JavaScript library coming next. (cit. Me)

Resources

@valentinogagliardi

Get in touch!

SLIDES

👇

@gagliardi_vale

Thank you!

Made with Slides.com