Svelte Flashcards

1
Q

What is a component in Svelte, and how is it defined?

A

A component in Svelte is a reusable, self-contained block of code that encapsulates HTML, CSS, and JavaScript. It is defined in a .svelte file.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

How can you add data to a Svelte component?

A

To add data to a Svelte component, you can use a

 tag inside the component and declare variables. For example:
<script>
let name = 'Svelte';
</script>
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

How do you reference a variable in the markup of a Svelte component?

A

To reference a variable in the markup of a Svelte component, you use curly braces. For example:

<h1>Hello {name}!</h1>

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

Can you use JavaScript expressions inside the curly braces in Svelte markup?

A

Yes, you can use any JavaScript expression inside the curly braces. For example:

<h1>Hello {name.toUpperCase()}!</h1>

This will result in a shoutier greeting by converting the name to uppercase.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

How can you use curly braces to control element attributes in a Svelte component?

A

In Svelte, you can use curly braces to control element attributes. For example:

<img src={src} />

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

Why is it important to include the alt attribute for an <img></img> element in Svelte?

A

Including the alt attribute is important for accessibility (a11y) in web apps. It provides a description of the image for people using screen readers or those with slow or unreliable internet connections.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

How do you use curly braces inside attributes in Svelte?

A

Curly braces inside attributes are used to include dynamic content. For instance:

<img src={src} alt=”A man dances.” />

You can replace the static text with dynamic content like variables declared in the

 block.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

What is the shorthand Svelte provides for attributes when the name and value are the same?

A

Svelte provides a shorthand for attributes where the name and value are the same. For example:

<img {src} alt=”{name} dances.” />

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

How can you render HTML directly into a Svelte component?

A

<p>{@html string}</p>

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

What caution should you take when using the {@html …} tag in Svelte?

A

When using the {@html …} tag in Svelte, it’s important to note that Svelte doesn’t perform any sanitisation of the expression inside {@html …}. If the content comes from untrusted sources, such as user-generated comments, manual escaping is crucial to prevent Cross-Site Scripting (XSS) attacks.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

Why is manual escaping necessary when using {@html …} in Svelte?

A

Manual escaping is necessary when using {@html …} in Svelte, especially for untrusted content like user comments. Without proper escaping, there is a risk of exposing users to Cross-Site Scripting (XSS) attacks. Svelte doesn’t automatically sanitize the content inside {@html …}.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

When might you use the {@html …} tag in a Svelte component?

A

The {@html …} tag in Svelte is useful when you need to render HTML directly into a component. It’s often used for scenarios like including HTML content from external sources or rendering dynamic HTML generated at runtime.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

What is the core mechanism in Svelte that ensures synchronisation between the DOM and the application state?

A

Svelte relies on a powerful system of reactivity to maintain synchronisation between the DOM and the application state.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

How does Svelte handle events and reactivity in the provided example involving a button?

A

In the given Svelte example, the on:click directive is used to wire up an event handler (increment) to the button’s click event. The increment function modifies the count variable, and Svelte’s reactivity system automatically updates the DOM to reflect the changes.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

What is the purpose of reactive declarations in Svelte, and how are they defined?

A

Reactive declarations in Svelte are used to compute values from other parts of a component’s state and automatically update when those parts change. They are defined using the syntax like $: doubled = count * 2;, where count is a variable being observed.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

In Svelte, when does a reactive declaration run, and how does it impact the rendering process?

A

A reactive declaration in Svelte runs whenever any of the referenced values change. It runs after other script code and before the component markup is rendered. Reactive declarations help in computing values dynamically and keeping the DOM in sync with the changing state.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
17
Q

Why won’t array methods like push automatically trigger updates in Svelte, and what is the consequence of not handling this issue?

A

In Svelte, array methods like push won’t automatically trigger updates because Svelte’s reactivity is triggered by assignments. Failing to address this issue would result in changes to the array not reflecting in the DOM, causing the UI to be out of sync with the state.

<!-- Example of not triggering reactivity -->

<script>
let numbers = [];
  function addNumber() {
    numbers.push(numbers.length + 1);
    // Without additional assignment, this won't trigger reactivity
  }
</script>
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
18
Q

What is the idiomatic solution in Svelte to ensure reactivity when using array methods like push, and how does it work?

A

The idiomatic solution in Svelte is to use the spread operator to create a new array with the updated values. For example: numbers = […numbers, numbers.length + 1];. This ensures that reactivity is triggered, and the DOM is updated accordingly.

<!-- Idiomatic solution to ensure reactivity with array methods -->

<script>
let numbers = [];
  function addNumber() {
    numbers = [...numbers, numbers.length + 1];
    // This triggers reactivity in Svelte
  }
</script>
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
19
Q

How can you handle reactivity when modifying arrays or objects in Svelte, and what is the simple rule of thumb to follow?

A

To handle reactivity when modifying arrays or objects in Svelte, you need to ensure that the variable name appears on the left side of the assignment. For example, instead of using obj.foo.bar = 2;, use obj = obj; after the modification to trigger reactivity.

<!-- Example of handling reactivity with object modification -->

<script>
let obj = { foo: { bar: 1 } };
  let foo = obj.foo;
  foo.bar = 2;
  obj = obj; // This triggers reactivity in Svelte
</script>
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
20
Q

What is the purpose of declaring properties (props) in Svelte components, and how are they declared?

A

In Svelte, declaring properties (props) is essential for passing data from a parent component to its children. Props are declared using the export keyword within a

 block in the child component.

<!-- Example of declaring a prop in Svelte -->

<script>
export let answer;
</script>
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
21
Q

Why does the syntax for declaring props in Svelte, using the export keyword, differ from typical JavaScript module exports?

A

The syntax for declaring props in Svelte with the export keyword may seem unconventional compared to typical JavaScript module exports. However, this syntax is specific to Svelte and is designed to facilitate the passing of data from parent to child components.

<!-- Example of declaring a prop in Svelte -->

<script>
export let answer;
</script>
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
22
Q

How can default values for props be specified in Svelte, and what is the purpose of providing default values?

A

In Svelte, default values for props can be specified using the export let variable = defaultValue; syntax. This allows a component to have a default value for a prop in case the prop is not explicitly provided when the component is used. Default values ensure that components work seamlessly even when certain props are omitted.

<!-- Example of specifying default values for props in Svelte -->

<script>
export let answer = 'a mystery';
</script>
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
23
Q

How does a component handle props that are not explicitly provided, and what is the behaviour when using default values?

A

When a component is used without explicitly providing a prop, it falls back to the default value specified for that prop. This ensures that the component can operate with sensible default values even if some props are not explicitly set by the parent component.

<!-- Example of using a component with and without explicitly providing a prop -->

<Nested answer={42}/>

<Nested></Nested>

<!-- Falls back to the default value 'a mystery' -->

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
24
Q

How can you pass multiple props to a Svelte component when the properties of an object correspond to the component’s expected props, and what is the benefit of using this approach?

A

In Svelte, you can use the ‘spread’ syntax ({…object}) to pass multiple props to a component when the properties of an object match the expected props of the component. This approach allows for a concise and readable way to pass all relevant properties without explicitly listing each one. It is particularly useful when the structure of the object aligns with the expected props of the component.

<!-- Example of spreading props onto a component -->

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

	const pkg = {
		name: 'svelte',
		speed: 'blazing',
		version: 4,
		website: 'https://svelte.dev'
	};
</script>

<PackageInfo {…pkg} />

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
25
Q

What is the alternative method for referencing all the props passed into a component, including ones not declared with export, and when might this be used?

A

To reference all props passed into a component, including ones not declared with export, you can access $$props directly. While this approach is not generally recommended due to optimization challenges for Svelte, it can be useful in rare cases where you need to access all passed props, including those not explicitly declared in the component.

<!-- Example of referencing all props using \$\$props -->

<script>
console.log(\$\$props); // Access all props, including undeclared ones
</script>
26
Q

How can you conditionally render markup in a Svelte component, and what is the syntax for creating a conditional block?

A

In Svelte, you can conditionally render markup by using the {#if} block. The syntax involves wrapping the markup you want to conditionally render inside {#if condition} and {/if} tags. The content inside the block will only be rendered if the specified condition is true.

<!-- Example of conditional rendering in Svelte -->

<script>
let count = 0;

  function increment() {
    count += 1;
  }
</script>

<button on:click={increment}>
Clicked {count} {count === 1 ? ‘time’ : ‘times’}
</button>

{#if count > 10}

<p>{count} is greater than 10</p>

{/if}

27
Q

What is the purpose of the {#if} block in Svelte, and how does it enable dynamic rendering based on a specified condition?

A

The {#if} block in Svelte enables dynamic rendering based on a specified condition. It allows you to conditionally include or exclude markup in the rendered output. If the condition inside the {#if} block evaluates to true, the content within the block is included; otherwise, it is excluded from the rendered output.

28
Q

How can you dynamically generate and render a list of buttons in a Svelte component, and what block structure do you use for this purpose?

A

To dynamically generate and render a list of buttons in a Svelte component, you use the {#each} block. The expression inside the block is typically an array or array-like object, and it iterates over each item in the array. You can access the current item and its index within the block. What is the general structure of the {#each} block in Svelte?

<!-- Example of dynamically rendering a list of buttons in Svelte using each block -->

<script>
let colors = ['red', 'green', 'blue'];
  let selected = 'red';
</script>

<div>
{#each colors as color, i}
<button
aria-current={selected === color}
aria-label={color}
style="background: {color}"
on:click={() => selected = color}
>{i + 1}</button>
{/each}
</div>

29
Q

Explain the purpose of the {#each} block in Svelte and how it facilitates the creation of dynamic lists in a component.

A

The {#each} block in Svelte is used to iterate over items in an array or array-like object, facilitating the dynamic creation of lists in a component. It allows you to generate repeated markup for each item, with the ability to access the current item and its index. This block simplifies the process of rendering lists of data by providing a clean and concise syntax for handling iteration.

30
Q

In Svelte, when using the {#each} block to iterate over items, why might it be important to specify a unique identifier or “key”? Provide an example and explain the purpose of using keys.

A

In Svelte’s {#each} block, specifying a unique identifier or “key” is important to help Svelte efficiently update the DOM when items change. The key uniquely identifies each item and informs Svelte which DOM nodes correspond to specific components. Without a key, Svelte defaults to adding and removing items at the end of the block, which may lead to unintended behavior. How can you specify a key in the {#each} block, and why is it beneficial for updating components in a list?

<!-- Example of using a key in Svelte's each block -->

<script>
let things = [
    { id: 1, name: 'Thing 1' },
    { id: 2, name: 'Thing 2' },
    { id: 3, name: 'Thing 3' }
  ];
</script>

{#each things as thing (thing.id)}
<Thing name={thing.name}/>
{/each}

31
Q

In Svelte, how does the {#await} block handle asynchronous data, and what are the three main sections within this block? Provide an example to illustrate the syntax and usage of the {#await} block.

A

The {#await} block in Svelte is used to handle asynchronous data and has three main sections: {:then}, {:catch}, and the initial waiting block. The {:then} section executes when the promise resolves successfully, providing access to the resolved value. The {:catch} section executes in case of promise rejection, allowing you to handle errors. The initial block is displayed while the promise is pending. Here’s an example illustrating the syntax and usage of the {#await} block:

<!-- Example of using the await block in Svelte -->

<script>
let promise = someAsyncFunction(); // Assuming someAsyncFunction returns a promise
</script>

{#await promise}

<p>...waiting</p>

<p>The number is {number}</p>

<p>{error.message}</p>

{/await}

32
Q

In Svelte, how can components dispatch events, and what is the role of createEventDispatcher? Provide an example of creating and dispatching an event in a Svelte component.

A

Components in Svelte can dispatch events using createEventDispatcher from the ‘svelte’ module. This function creates an event dispatcher linked to the component instance. The dispatcher is then used to send custom events with specific data. Here’s an example:

<!-- Example of creating and dispatching an event in Svelte -->

<!-- Inner.svelte -->

<script>
import { createEventDispatcher } from 'svelte';

  const dispatch = createEventDispatcher();

  function sayHello() {
    dispatch('message', {
      text: 'Hello!'
    });
  }
</script>

<!-- App.svelte -->

<Inner on:message={handleMessage} />

<script>
function handleMessage(event) {
    console.log('Received message:', event.detail.text);
  }
</script>

In this example, createEventDispatcher is used to create the dispatch function in Inner.svelte. The component then dispatches a ‘message’ event with the data object { text: ‘Hello!’ }. In App.svelte, an on:message handler is used to listen for this event and execute the handleMessage function when it occurs.

33
Q

How does Svelte handle the forwarding of component events in a nested component structure, and what shorthand does it provide for simplifying the process? Provide an example.

A

In Svelte, unlike DOM events, component events don’t bubble up the component hierarchy. To listen to an event on a deeply nested component, intermediate components must forward the event. Svelte provides a shorthand for this forwarding process using the on:eventname event directive without a value, which means ‘forward all events with the specified name’. Here’s an example:

<!-- Outer.svelte -->

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

<Inner></Inner>

In this example, the on:message event directive in Outer.svelte means that any ‘message’ events emitted by the Inner component will be automatically forwarded up the component hierarchy without the need for explicit event handlers.

34
Q

How does Svelte allow the forwarding of DOM events in a component, and what is an example of forwarding a click event in a Svelte component?

A

Svelte allows the forwarding of DOM events in a component by simply using the on:eventname event directive. Here’s an example of forwarding a click event in a Svelte component:

<!-- BigRedButton.svelte -->

<button>
Push
</button>

In this example, the on:click event directive in BigRedButton.svelte forwards any click events that occur on the <button> element, making it easy to capture and handle those events in the parent components.</button>

35
Q

In Svelte, what is the purpose of the bind:value directive, and how does it simplify the handling of data flow between a parent component and an input element?

A

The bind:value directive in Svelte simplifies data flow between a parent component and an input element. When applied to an input element, it establishes a two-way binding, ensuring that changes to the value of the input element automatically update the associated variable in the parent component, and vice versa. This eliminates the need for explicit event handlers and reduces boilerplate code.

<script>
let name = 'world';
</script>

<input bind:value={name} />

<h1>Hello {name}!</h1>

36
Q

How does the bind:value directive simplify handling the data flow with <select> elements in Svelte, and what should be considered regarding the initial value of the bound variable?</select>

A

In Svelte, the bind:value directive simplifies data flow with <select> elements. When applied to a <select> element, it establishes a two-way binding with the associated variable. Changes to the selected option in the <select> element automatically update the variable, and vice versa. However, it’s important to note that until the binding is initialized, the associated variable remains undefined, so caution is needed when referencing it in the template before initialization.</select></select></select>

37
Q

How does the bind:value directive work in Svelte, and in what scenarios is it particularly useful?

A

The bind:value directive in Svelte establishes a two-way binding between a variable in the component’s script and a form input element. Changes to the variable update the input value, and changes to the input value update the variable. This is particularly useful for managing the state of form elements, such as <input></input> and <select>. It eliminates the need for manual event handlers, reducing boilerplate code and enhancing code readability.</select>

<!-- Example with input element -->

<script>
let name = '';
</script>

<input bind:value={name} />

<!-- Example with select element -->

<script>
let selected = '';
</script>

<select bind:value={selected}>
<!-- options here -->
</select>

38
Q

Explain the purpose of the on:change event handler when used in conjunction with the bind:value directive on a <select> element in Svelte.</select>

A

In Svelte, when using the bind:value directive with a <select> element, the on:change event handler is often added to handle changes in the selected value. The on:change event is triggered when the user makes a selection, and it allows for additional logic or side effects to be executed in response to the change. It’s commonly used to update other parts of the component’s state or trigger actions based on the user’s selection.</select>

<!-- Example with select element -->

<script>
let selected = '';
  let answer = '';

  function handleSelectionChange() {
    answer = ''; // Additional logic here
  }
</script>

<select bind:value={selected} on:change={handleSelectionChange}>
<!-- options here -->
</select>

39
Q

How does the bind:value directive work with a <select> element when the multiple attribute is present, and what does it allow users to do?</select>

A

In Svelte, when the bind:value directive is used with a <select> element that has the multiple attribute, it creates a two-way binding with an array variable. Users can select multiple options from the dropdown, and the selected values are automatically stored in the bound array. This simplifies the handling of multiple selections and ensures that changes to the selected options are reflected in the array variable.</select>

<!-- Example with select element and multiple attribute -->

<script>
let flavours = [];
</script>

<select multiple bind:value={flavours}>
<!-- options here -->
</select>

40
Q

What is the purpose of the multiple attribute on a <select> element in HTML, and how is it utilised in Svelte?</select>

A

The multiple attribute on a <select> element in HTML allows users to select multiple options from the dropdown, rather than just a single option. In Svelte, when binding the value of a <select> element with bind:value, the multiple attribute is used to signify that the associated variable should be an array to store multiple selected values. This enables the creation of multi-select dropdowns, providing a convenient way to manage and manipulate lists of selected items.</select></select>

<!-- Example with select element and multiple attribute -->

<script>
let flavours = [];
</script>

<select multiple bind:value={flavours}>
<!-- options here -->
</select>

41
Q

What is the purpose of the onMount function in Svelte?

A

The onMount function in Svelte allows you to run code after a component is first rendered to the DOM, making it suitable for actions or setups needed when the component is displayed.

42
Q

Why is it necessary to return a cleanup function from the onMount callback in this Svelte example?

A

Returning a cleanup function is essential to stop ongoing processes or animations initiated in the onMount callback. In this case, it cancels the animation frame to prevent it from persisting after the component is destroyed, avoiding memory leaks.

onMount(() => {
const canvas = document.querySelector(‘canvas’);
const context = canvas.getContext(‘2d’);

let frame = requestAnimationFrame(function loop(t) {
	frame = requestAnimationFrame(loop);
	paint(context, t);
});

return () => {
	cancelAnimationFrame(frame);
}; });
43
Q

What is the purpose of the beforeUpdate and afterUpdate functions in Svelte?

A

The beforeUpdate function in Svelte schedules work to happen immediately before the DOM is updated, while afterUpdate is used for running code once the DOM is in sync with the component’s data. They are helpful for imperatively handling tasks that are challenging to achieve in a purely state-driven way.

44
Q

In the provided Svelte code snippet, what issue is being addressed, and how is it resolved using beforeUpdate and afterUpdate?

A

The issue being addressed is the inconvenience of manually scrolling the chat window in the Eliza chatbot. beforeUpdate calculates if the chat window is already scrolled to the bottom, and afterUpdate ensures automatic scrolling if needed, creating a smoother user experience.

let div;
let autoscroll = false;

beforeUpdate(() => {
if (div) {
const scrollableDistance = div.scrollHeight - div.offsetHeight;
autoscroll = div.scrollTop > scrollableDistance - 20;
}
});

afterUpdate(() => {
if (autoscroll) {
div.scrollTo(0, div.scrollHeight);
}
});

45
Q

Why is it necessary to check for the existence of div before reading its properties in the beforeUpdate function?

A

beforeUpdate may run before the component has mounted, so checking for the existence of div ensures that properties are accessed only when the element is available, preventing errors.

46
Q

What is the purpose of the ‘tick’ function in Svelte, and when is it typically used?

A

The ‘tick’ function in Svelte is used to ensure that any pending state changes have been applied to the DOM. It returns a promise that resolves when these changes are processed. It is typically used when you want to perform actions immediately before or after state changes to avoid unexpected behavior, especially when dealing with asynchronous tasks.

47
Q

Explain the significance of using the tick function in the provided Svelte code snippet. What problem does it address?

A

In the given code snippet, the tick function is employed to address the issue of the cursor jumping to the end of a <textarea> when the tab key is pressed. By awaiting tick before setting the selectionStart and selectionEnd properties, it ensures that any pending state changes are applied, preventing the undesired cursor behavior caused by the delayed DOM updates.</textarea>

import { tick } from ‘svelte’;

let text = Select some text and hit the tab key to toggle uppercase;

// …

await tick();
this.selectionStart = selectionStart;
this.selectionEnd = selectionEnd;

48
Q

Explain why Svelte delays updating the DOM immediately after a state change, and how does the tick function contribute to this behavior?

A

Svelte delays updating the DOM immediately after a state change to wait and batch changes effectively. This delay allows the framework to see if there are any other pending changes in the same microtask, reducing unnecessary work.

The tick function in Svelte contributes to this behaviour by providing a way to wait for these pending changes to be applied. It returns a promise that resolves when the DOM is updated, ensuring that subsequent actions are executed at the appropriate time in the lifecycle.

49
Q

What is a store in Svelte, and how is it defined?

A

In Svelte, a store is an object with a subscribe method that allows interested parties to be notified whenever the store value changes. It serves as a means of managing and sharing state across multiple components or JavaScript modules. A store can be writable, meaning it has set and update methods in addition to subscribe.

50
Q

Explain the role of the count store in the provided Svelte code snippet, and how is it used in Incrementer.svelte and Resetter.svelte?

A

The count store is a writable store defined in stores.js with set and update methods in addition to subscribe. In Incrementer.svelte, the increment function uses count.update to increment the value of the count store. In Resetter.svelte, the reset function uses count.set(0) to reset the value of the count store to zero. This allows components to interact with and modify the shared state managed by the count store.

// Incrementer.svelte
function increment() {
count.update((n) => n + 1);
}

// Resetter.svelte
function reset() {
count.set(0);
}

51
Q

What is the significance of making the count store writable in Svelte, and how does it affect the ability to update its value in different components?

A

Making the count store writable in Svelte means that it has set and update methods, allowing components to both directly set a new value (set) and update the value based on the current value (update). This makes it flexible for different components to interact with and modify the shared state managed by the count store, providing a convenient way to synchronize and share state across components or modules.

52
Q

Explain the potential memory leak issue in the Svelte app, how it arises, and how it can be addressed using the onDestroy lifecycle hook.

A

In the Svelte app, the potential memory leak arises from subscribing to the count store without unsubscribing. If the component is instantiated and destroyed many times, each instantiation results in a new subscription, leading to an accumulation of subscriptions over time. To address this, the onDestroy lifecycle hook is used to call the unsubscribe function, preventing the memory leak by unsubscribing when the component is being destroyed.

<script>
import { onDestroy } from 'svelte';
    import { count } from './stores.js';

    let count_value;

    const unsubscribe = count.subscribe(value => {
        count_value = value;
    });

    onDestroy(unsubscribe);
</script>
53
Q

How does Svelte provide a more concise and convenient way to handle store subscriptions using the $count syntax, and where can it be used in a Svelte component?

A

In Svelte, the $count syntax allows for auto-subscription to a store value, making it more concise and convenient than manually handling subscriptions. This syntax can be used in the markup (HTML) section as well as in the

 section of a Svelte component. It automatically handles subscription and unsubscription, reducing the need for boilerplate code.
<script>
import { onDestroy } from 'svelte';
    import { count } from './stores.js';

    let count_value;

    $: count_value = $count;

    onDestroy(() => {});
</script>

<h1>The count is {$count}</h1>

54
Q

Explain the significance of the $ prefix in Svelte and how it is used in relation to store variables.

A

In Svelte, the $ prefix is a special character indicating that the variable following it refers to a store value. It is used to provide auto-subscription to the store, eliminating the need for manually handling subscriptions and unsubscriptions. The $count syntax, for example, allows easy access to the value of the count store, and it can be used in both the markup and the script sections of a Svelte component. Svelte reserves the $ prefix, preventing the declaration of user-defined variables with this prefix.

55
Q

Explain the purpose of a readable store in Svelte and how it differs from a writable store. Provide an example of creating a readable store using the readable function in Svelte.

A

A readable store in Svelte is designed for situations where you want to expose a value to subscribers but don’t want external entities to modify that value. Unlike writable stores, readable stores are not directly writable from outside the store. They are ideal for scenarios such as representing the mouse position or the user’s geolocation.

To create a readable store using the readable function, you provide an initial value (which can be null or undefined) as the first argument and a start function as the second argument. The start function takes a set callback and returns a stop function. The set callback is used to update the store’s value, and the start function is called when the store gets its first subscriber. The stop function is called when the last subscriber unsubscribes.

// stores.js
import { readable } from ‘svelte/store’;

export const time = readable(new Date(), function start(set) {
const interval = setInterval(() => {
set(new Date());
}, 1000);

return function stop() {
    clearInterval(interval);
}; });
56
Q

Differentiate between readable and writable stores in Svelte. What scenarios are readable stores suitable for, and how do they handle modifications to the store’s value?

A

In Svelte, a readable store is intended for scenarios where you want to expose a value to subscribers without allowing external modifications. It is not directly writable from outside the store. Readable stores are suitable for situations like representing the mouse position or user geolocation.

Writable stores, on the other hand, allow both reading and writing of values. They are suitable when you need to share state that can be modified by different parts of the application.

Readable stores handle modifications internally through the set callback provided in the start function. The set callback is responsible for updating the store’s value. External entities can’t directly modify the store’s value; they can only subscribe to changes.

57
Q

Explain the role of the start and stop functions in a readable store’s definition. How are these functions used in the context of a readable store in Svelte?

A

In the context of a readable store in Svelte, the start function is called when the store gets its first subscriber. It takes a set callback as an argument, and this callback is used to update the store’s value. The start function is where you set up any necessary processes, such as intervals or event listeners.

The stop function, returned by the start function, is called when the last subscriber unsubscribes. It is responsible for cleaning up any resources or stopping processes that were set up in the start function. For example, if the readable store involves an interval, the stop function can be used to clear that interval.

These functions ensure that the store is efficiently managed, with processes running only when there are active subscribers and stopping when there are none.

export const time = readable(new Date(), function start(set) {
// Setup code, e.g., interval
const interval = setInterval(() => {
set(new Date());
}, 1000);

// Cleanup function
return function stop() {
    clearInterval(interval);
}; });
58
Q

Explain the use of the derived function in Svelte stores. Provide an example of creating a derived store and describe how it can be based on the value of one or more other stores.

A

The derived function in Svelte allows you to create a store whose value is based on the value of one or more other stores. It enables you to derive a new store from existing ones, facilitating the creation of computed or transformed values.

// stores.js
import { derived } from ‘svelte/store’;
import { time } from ‘./timeStore.js’;

export const elapsed = derived(
time,
($time) => Math.round(($time - start) / 1000)
);

In this example, a derived store named elapsed is created based on the time store. The second argument to derived is a callback function that specifies how to derive the new value. Here, it calculates the elapsed time in seconds by subtracting the start time and rounding.

You can also derive a store from multiple input stores and explicitly set a value. This provides flexibility for creating stores that depend on various data sources or involve asynchronous computations.

For more details, refer to the Svelte API reference.

59
Q

Explain how custom stores can be created in Svelte, and provide an example of a custom store with domain-specific logic.

A

Custom stores in Svelte are created by implementing the subscribe method along with any additional methods required for domain-specific functionality. As long as an object correctly implements subscribe, it can serve as a store. Here’s an example of a custom store for counting:

// stores.js
import { writable } from ‘svelte/store’;

function createCount() {
const { subscribe, set, update } = writable(0);

return {
    subscribe,
    increment: () => update((n) => n + 1),
    decrement: () => update((n) => n - 1),
    reset: () => set(0)
}; }

export const count = createCount();

In this example, the createCount function creates a custom store named count. The store has the standard subscribe method along with custom methods like increment, decrement, and reset. This encapsulates the logic for manipulating the count value and provides a cleaner and more expressive API for interacting with the store.

60
Q

Explain how writable stores in Svelte can be bound to components, and provide an example of binding a writable store to an input element.

A

Writable stores in Svelte can be bound to components using the bind:value syntax, similar to local component state. For example, if a writable store named name is defined, it can be bound to an <input></input> element in a Svelte component:

<!-- App.svelte -->

<script>
import { name } from './stores.js';
</script>

<input bind:value={$name}>

In this example, changing the input value will automatically update the name store and all its dependents.

Additionally, direct assignments to store values inside a component can be made. For instance, adding an event handler to a button for updating the name store:

<!-- App.svelte -->

<script>
import { name } from './stores.js';
</script>

<input bind:value={$name}>
<button on:click={() => $name += ‘!’}>
Add exclamation mark!
</button>

The $name += ‘!’ assignment is equivalent to name.set($name + ‘!’), demonstrating a convenient way to modify writable store values within a Svelte component.

61
Q
A