Svelte Search

About

How does the context API works?

The Svelte Context API is a powerful feature that allows you to share data between components without having to pass props explicitly through every level of the component tree. Let's break down how it works and why it's useful.

What is Context?

Context in Svelte is a way to share data between a parent component and its descendants (child components, grandchildren, etc.). It's particularly useful for sharing data that is needed by many components at different levels of the hierarchy, without having to pass that data through props at every level.

How Does It Work?

The Context API in Svelte revolves around two main functions: setContext and getContext.

  1. setContext(key, value): This function is used to associate a value with a specific key in the context of the current component. This value will be available to all child components (including slotted content).

    <script>
      import { setContext } from 'svelte';
    
      // Set a value in the context
      setContext('user', { name: 'Alice', age: 30 });
    </script>
    
  2. getContext(key): This function is used to retrieve the value associated with a specific key from the context of the nearest parent component.

    <script>
      import { getContext } from 'svelte';
    
      // Retrieve the value from the context
      const user = getContext('user');
    </script>
    
    <p>Welcome, {user.name}!</p>
    

Key Points to Understand

  • Scoped to Component Tree: Context is scoped to the component tree. This means that the context set in a parent component is only available to its descendants. It's not global, so it won't leak state to other parts of your app.

  • Not Reactive by Default: Context is not inherently reactive. If you need reactive values, you can pass a $state object into the context. The properties of this object will be reactive.

    <script>
      import { setContext } from 'svelte';
    
      // Create a reactive state object
      let user = $state({ name: 'Alice', age: 30 });
    
      // Set the reactive state object in the context
      setContext('user', user);
    </script>
    
  • Initialization Phase: Both setContext and getContext must be called during the component's initialization phase. This means they should be called directly within the <script> tag of the component, not inside functions or event handlers.

Practical Example

Let's consider a practical example where we have a parent component that sets a user context and a child component that retrieves and uses this context.

Parent.svelte:

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

  // Set a user object in the context
  setContext('user', { name: 'Alice', age: 30 });
</script>

<Child />

Child.svelte:

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

  // Retrieve the user object from the context
  const user = getContext('user');
</script>

<p>Welcome, {user.name}!</p>

Why Use Context?

  • Avoid Prop Drilling: Context helps you avoid "prop drilling," where you have to pass props through multiple levels of components just to get data to a deeply nested child.

  • Server-Side Rendering (SSR) Safety: Since context is scoped to the component tree, it's safe to use in server-side rendered applications without risking state leakage between different users or sessions.

Additional Context Functions

  • hasContext(key): This function checks if a given key has been set in the context of a parent component.

    <script>
      import { hasContext } from 'svelte';
    
      if (hasContext('user')) {
        // Do something if the context exists
      }
    </script>
    
  • getAllContexts(): This function retrieves the entire context map of the closest parent component. This can be useful if you need to pass the existing context to a programmatically created component.

    <script>
      import { getAllContexts } from 'svelte';
    
      const contexts = getAllContexts();
    </script>
    

Conclusion

The Svelte Context API is a clean and efficient way to share data between components in a structured manner. By using setContext and getContext, you can avoid prop drilling and ensure that your state is scoped appropriately, making your application easier to maintain and reason about. Remember that context is not reactive by default, but you can make it reactive by passing a $state object. Always ensure that context operations are performed during component initialization to avoid runtime errors.