You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Svelte 5中hooks.client.ts如何用$state?Pocketbase认证赋值报错求助

Pocketbase + Svelte 5 认证实现问题解决方案

问题描述

我正在结合Pocketbase与Svelte 5实现认证功能,参考相关仓库的hooks.client.ts实现后,遇到两个问题:

  1. 在$lib/stores/user.svelte.ts中定义$state变量后,在+layout.svelte中直接赋值时VSCode提示错误:Cannot assign to import svelte(constant_assignment)。
  2. 不清楚如何在hooks.client.ts中使用$state。

相关代码:

// src/lib/stores/user.svelte.ts
import { type AuthModel } from 'pocketbase'
export let currentUser: AuthModel | null = $state(null)
// src/+layout.svelte
<script lang="ts">
    import { pb } from '$lib/pocketbase'
    import { currentUser } from '$lib/stores/user.svelte'

    let { children } = $props()

    pb.authStore.loadFromCookie(document.cookie)
    pb.authStore.onChange(() => {
        currentUser = pb.authStore.model
        document.cookie = pb.authStore.exportToCookie({ httpOnly: false })
    }, true)
</script>

{@render children()}

问题1:解决Cannot assign to import错误

Svelte 5中从.svelte.ts导出的$state变量默认是只读的,直接赋值会触发常量赋值错误,可通过以下两种方案解决:

方案A:封装状态与修改函数

修改user.svelte.ts,将状态私有化,导出只读状态和修改函数:

// src/lib/stores/user.svelte.ts
import { type AuthModel } from 'pocketbase'

// 内部私有状态
let _currentUser: AuthModel | null = $state(null)

// 导出只读的派生状态
export const currentUser = $derived(_currentUser)
// 导出修改状态的函数
export const setCurrentUser = (user: AuthModel | null) => {
    _currentUser = user
}

在+layout.svelte中调用修改函数更新状态:

// src/+layout.svelte
<script lang="ts">
    import { pb } from '$lib/pocketbase'
    import { currentUser, setCurrentUser } from '$lib/stores/user.svelte'

    let { children } = $props()

    pb.authStore.loadFromCookie(document.cookie)
    pb.authStore.onChange(() => {
        setCurrentUser(pb.authStore.model)
        document.cookie = pb.authStore.exportToCookie({ httpOnly: false })
    }, true)
</script>

{@render children()}

方案B:使用可写状态引用(Svelte 5最新语法)

如果使用Svelte 5最新版本,也可以通过函数封装可写状态,避免直接暴露可写变量:

// src/lib/stores/user.svelte.ts
import { type AuthModel } from 'pocketbase'

export function createUserStore() {
    let currentUser: AuthModel | null = $state(null)
    return {
        get currentUser() { return currentUser },
        set currentUser(user: AuthModel | null) { currentUser = user }
    }
}

在组件中实例化后使用:

// src/+layout.svelte
<script lang="ts">
    import { pb } from '$lib/pocketbase'
    import { createUserStore } from '$lib/stores/user.svelte'

    const userStore = createUserStore()
    let { children } = $props()

    pb.authStore.loadFromCookie(document.cookie)
    pb.authStore.onChange(() => {
        userStore.currentUser = pb.authStore.model
        document.cookie = pb.authStore.exportToCookie({ httpOnly: false })
    }, true)
</script>

{@render children()}

问题2:在hooks.client.ts中使用状态管理

hooks.client.ts是普通.ts文件,无法直接使用$state语法,可通过以下两种方案实现状态同步:

方案A:使用createSignal底层API

Svelte 5提供的createSignal可以在普通.ts文件中使用,替代$state实现状态管理:

// src/lib/stores/user.ts
import { type AuthModel } from 'pocketbase'
import { createSignal } from 'svelte'

// 创建信号,返回可读函数和可写函数
export const [currentUser, setCurrentUser] = createSignal<AuthModel | null>(null)

在hooks.client.ts中直接调用更新函数:

// src/hooks.client.ts
import { pb } from '$lib/pocketbase'
import { setCurrentUser } from '$lib/stores/user'

pb.authStore.loadFromCookie(document.cookie)
pb.authStore.onChange(() => {
    setCurrentUser(pb.authStore.model)
    document.cookie = pb.authStore.exportToCookie({ httpOnly: false })
}, true)

组件中可通过$currentUser订阅状态变化。

方案B:通过自定义事件同步状态

如果坚持使用.svelte.ts的$state,可以在hooks.client.ts中触发自定义事件,让组件监听并更新状态:

// src/hooks.client.ts
import { pb } from '$lib/pocketbase'

pb.authStore.loadFromCookie(document.cookie)
pb.authStore.onChange(() => {
    document.cookie = pb.authStore.exportToCookie({ httpOnly: false })
    // 触发自定义auth变更事件
    window.dispatchEvent(new CustomEvent('auth-change', {
        detail: pb.authStore.model
    }))
}, true)

在+layout.svelte中监听事件更新状态:

// src/+layout.svelte
<script lang="ts">
    import { pb } from '$lib/pocketbase'
    import { setCurrentUser } from '$lib/stores/user.svelte'

    let { children } = $props()

    // 初始化加载状态
    setCurrentUser(pb.authStore.model)

    // 监听自定义事件更新状态
    window.addEventListener('auth-change', (e) => {
        setCurrentUser((e as CustomEvent).detail)
    })
</script>

{@render children()}

内容的提问来源于stack exchange,提问作者Nikolay Dyankov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 21:35:15