本文介绍了设置存储值的 Svelte 用户注册问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

你好:)

我正在尝试注册一个用户,成功后,将上下文设置为新注册的用户,然后导航到主页.服务器正确响应并注册用户,但是当调用 setContext 时,我收到以下错误:index.mjs:552 Uncaught (in promise) Error: Function called external component initialization"

I'm trying to register an user and after success, setContext to newly registered user and then navigate to home. Server properly responds and registers user, but when setContext is called i get the following error: "index.mjs:552 Uncaught (in promise) Error: Function called outside component initialization"

    <script>
    import { setContext } from 'svelte'

    async function handleRegistration(e) {
        let user = {
                    firstname: e.target.firstname.value,
                    lastname: e.target.lastname.value,
                }

                fetch('http://localhost:3001/api/auth/register', {
                    method: 'POST',
                    headers: {'Content-Type':'application/json'},
                    body: JSON.stringify(user)
                })
                .then(res => res.json())
                .then(res => {
                    if(res.accessToken) {
                        user.accessToken = res.accessToken
                        user.refreshToken = res.refreshToken
                        setContext('userData', user)
                        navigate("/", { replace: true })
                    }
                })

                updateContext(user)
            }
    }
</script>

<form class="registration" on:submit|preventDefault="{handleRegistration}">
</form>

我做错了什么?

推荐答案

setContext 必须在组件初始化期间同步调用.也就是说,从 标签的根开始:

setContext must be called synchronously during component initialization. That is, from the root of the <script> tag:

<script>
  import { setContext } from 'svelte'

  console.log('init')

  setContext(...) // OK

  setTimeout(() => {
    setContext(...) // Not OK (we're not synchronous anymore)
  }, 0)
<script>

<h1>My Svelte Component</h1>

这在 docs 中的一个有点神秘的句子中提到:

This is mentioned in a little cryptic sentence in the docs:

与生命周期函数一样,必须在组件初始化期间调用.

其他生命周期函数有 onMountonDestroy 等.setContext 是这样一种生命周期方法,可以说不太明显.

Other lifecycle functions are onMount, onDestroy, etc. It is arguably less obvious that setContext is such a lifecycle method.

编辑

我刚刚重读了你的问题,并意识到这实际上只是回答了一半......

I just reread your question, and realized this really just answer half of it...

setContext/getContext 只能在组件初始化时使用一次,那么如何通过上下文共享 API 结果呢?相关:如果调用是在 Svelte 组件之外进行的,您将如何共享这些 API 结果,其中 setContext 将更不可能(并且可以说 API 调用的位置更好,以便分离关注事项)?

setContext / getContext can only be used once at component init, so how do you share your API result through context? Related: how would you share those API results if the call was made outside of a Svelte component, where setContext would be even more out of the question (and the API call would arguably be better located, for separation of concerns matters)?

好吧,把商店放在你的上下文中.

Well, put a store in your context.

例如,对于可写存储:

<script>
  import { getContext } from 'svelte'

  const userData = getContext('userData')

  function handleRegistration(e) {
    doSuperApiCall()
      .then(data => {
        userData.set(data)
        // or fancy:
        $userData = data
      })
      .catch(...)
  }
</script>
...

在一些更高的包装组件(例如)的初始化期间将此存储置于上下文中:

Put this store in context during the init of some higher wrapping component (the like of <App>):

<script>
  import { setContext } from 'svelte'
  import { writable } from 'svelte/store'

  const userData = writable(null)

  setContext('userData', userData)
</script>

<slot />

通过这种方式,您可以使用 getContext 从(例如) 的任何子组件轻松访问您的商店,并异步读取/写入它.

This way you can easily access your store with getContext from any child component of (say) <App>, and read to / write from it asynchrnously.

这篇关于设置存储值的 Svelte 用户注册问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-24 13:42