Hello again! This is the fourth post where I explore Svelte from a React developer's perspective. You can check out the previous posts in the links below:
Before I start talking about today's topic, I just want to write about my thoughts on what's going on in the world regarding COVID-19. Since my last article things have gotten pretty serious in some countries. We, as software developers may be a little luckier than other people cause we can most likely WFH. Still, we have to follow the advice given by the health authorities so we can help stop spreading the virus. You may not get seriously ill if you are young and healthy but think about the people that could get bad like the elders or people with special health conditions. Let's follow the best practices on this and help solve this bug 👍.
In today's post, I'm taking a look at logic and how Svelte compares with React in that matter.
When we think about logic, what first comes to mind are the if/else blocks.
Let's check them out:
If/Else Blocks
Svelte introduces some special syntax to let us declare these blocks inside our markup. A bit similar to React were we can put some Javascript code inside our JSX using curly brackets.
This is very simple and the code explains by itself:
<script>
let x = 7;
</script>
{#if x > 10}
<p>{x} is greater than 10</p>
{:else if 5 > x}
<p>{x} is less than 5</p>
{:else}
<p>{x} is between 5 and 10</p>
{/if}
As you can see in the example above, you can use the variable x inside these blocks, having x defined in your script section.
The only things you have to remember here are that the #
character indicates a block opening tag, the /
character indicates a block closing tag and the :
character, as in {:else}
, indicates a block continuation tag.
Think of this like just doing your normal if/else blocks from Javascript with some slightly different syntax.
Each Blocks
Iterating over arrays or array-like structures will always be a requirement when working in web applications. In React we use Javascript functions such as map() or forEach(). Svelte's logic does not go far from this. The following code shows us the way of iterating over an array and generating a list item element for each item in the array.
<script>
let books = [
{ id: 'book_1', name: '1984', author: 'George Orwell' },
{ id: 'book_2', name: 'The Art of War', author: 'Sun Tzu' },
{ id: 'book_3', name: 'The Shinning', author: 'Stephen King' }
];
</script>
<h1>Books I really like</h1>
<ul>
{#each books as book, i}
<li><a target="_blank" href="https://www.bookstore.com/{book.id}">
{i + 1}: {book.name} by {book.author}
</a></li>
{/each}
</ul>
As you can see, we are iterating over the books array, calling each item as book and also receiving the current index as i. We can then use the variables book and i inside our list item element.
Await blocks
It is very common on web applications to make asynchronous calls. Most likely to fetch some data from a remote server. The usual approach to dealing with this is showing some loading message by default while we get our response.
The way I am used to doing this in React is managing some variables in the state that will let me know if the request is pending and if it succeeded or failed. Then in my JSX I would usually validate against these variables to determine which UI element to render. There are libraries to handle this with less code but the approach is the same.
Svelte works in a similar way and lets us declare some await blocks in our markup. We have to specify the promise we are waiting for and our then and catch blocks if needed.
If you are familiar with Promises and Async Functions you should be able to get this right away.
Let's take a look at the following example from the tutorial with some comments I added:
<script>
// This is the promise we are gonna await
// In this example, we are calling getRandomNumber from the beginning
// But this doesn't have to be this way if you want to call it on demand.
// The variable promise will get what getRandomNumber returns once it resolves
let promise = getRandomNumber();
async function getRandomNumber() {
// Here are some async operations, meaning that we won't get
// the data right away. Let's say the random number comes from
// a remote server.
const res = await fetch(`tutorial/random-number`);
const text = await res.text();
// This is what we'll get in our markup once the promise resolves or fails
if (res.ok) {
return text;
} else {
// We can catch this error in our markup
throw new Error(text);
}
}
function handleClick() {
// Promise will get what getRandomNumber returns once it resolves
promise = getRandomNumber();
}
</script>
<button on:click={handleClick}>
generate random number
</button>
<!-- We'll show some ...waiting message while the promise resolves -->
{#await promise}
<p>...waiting</p>
<!-- If the promise succeeds we show the result -->
{:then number}
<p>The number is {number}</p>
<!-- We catch any error the promise could return -->
{:catch error}
<p style="color: red">{error.message}</p>
{/await}
Not so different right?
Svelte has shown us that while it introduces some new syntax, it is all very similar to what we are used to. If you've worked with React or just know some Javascript you won't have serious problems getting into all this.
This is all for the fourth part. I have decided that I'll change the approach of this series and instead of going through the topics one by one I'll start working on a small Svelte app. Hopefully with several components and some data fetching. This way I'll be able to work with more realistic scenarios and get a better perspective of the framework. I'll try to get something cool in a couple of weeks!
Thanks for reading and stay tuned!
Follow me on twitter: @jdelvx
Top comments (1)
Good series. What I find most interesting coming from React to Svelte is how these two tools affect my thinking and problem solving when I use them. I find that with React I need to think about React itself at least as much as I need to think about my problem and with Svelte I feel much more empowered and able to express ideas directly.