# Global States (SPA)

## Introduction

You might be familliar with `useContext()` function of the React framework that allows values to be available without passing props. It is a real hassle to setup and often time very confusing. This chapter will simply show a method of how the `State` function can be used in WebLabs to offer states that are globally available.

{% hint style="warning" %}
This only work for SPAs and not on pages served from a server. If you are using `AppRouter()` and `AppNavigator()` it will work just fine since it is part of SPA WebLabs package
{% endhint %}

## Problem & Solution

Let's say we want to make a social media application using Supabase and WebLabs, and we want to retrive the user to show appropriate routes to them. But this means we need to load the user at every view, or load them once in a state and pass it to every component. That sounds very inefficient and will go out of hand very easily.

Rather, we can do is create a separate supabase file as `supabase.ts` and do something like this:

```typescript
import { createClient } from '@supabase/supabase-js'
import type { User } from '@supabase/supabase-js'
import { State } from '@weblabsjs/core'

// Create a single supabase client for interacting with your database
export const supabase = createClient('https://xyzcompany.supabase.co', 'public-anon-key')
export const user = State<User | undefined>(undefined) 
```

Now we can import this `user` state and update it in our splash screen, and then divert them to other routes accordingly.

We can use `AppRouter()` to create SPA Routes and navigate them using the `AppNavigator()` function, so it might look somewhat like this:

```typescript
//this is the splash view

import { div, p } from "@weblabsjs/core/components";
import { user as GlobalUser, supabase } from "../supabase";
import { AppNavigator, onLoad } from "@weblabsjs/core";

export default function SplashView() {

    //in this view, we are responsible for loading
    //the user and setting it in the global user object

    onLoad(async () => {
            
            const { data: { user } } = await supabase.auth.getUser()

            if ( user != undefined ) {
    
                GlobalUser.set(user)
                AppNavigator("/feed")
    
            } else {
                AppNavigator("/login")
            }

    })

    return div(
        //your splash screen goes here
    )
}
```

You can also use state subscriptions to directly interfere with the state without explicitly have to deal with the user state, and you can use some subscription-based functions like `onAuthStateChange()` in conjunction with `State.subscribe()` to detect login interfaces accurately.

You can also use this pattern for work cases like that of `Redux` does, since weblabs state can be shared amongst various components, and you can also do what redux does of immutable data array system extending the State.

There is no limit to what you can do with WebLabs. It is made of simple functions that can solve almost any problem, since they work synchronously so well.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://creatorlabs.gitbook.io/weblabs/understanding-weblabs/advanced-state/global-states-spa.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
