toH*_*oHo 2 svelte svelte-store
你好:)
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>
Run Code Online (Sandbox Code Playgroud)
What am I doing wrong?
setContext必须在组件初始化期间同步调用。也就是说,从<script>标签的根开始:
<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>
Run Code Online (Sandbox Code Playgroud)
这在文档中的一个小神秘句子中提到:
与生命周期函数一样,必须在组件初始化期间调用它。
其他生命周期函数是onMount、onDestroy等。可以说,setContext这种生命周期方法不太明显。
编辑
我刚刚重读了你的问题,并意识到这真的只是回答了一半......
setContext/getContext只能在组件初始化时使用一次,那么如何通过上下文共享 API 结果呢?相关:如果调用是在 Svelte 组件之外进行的,您将如何共享这些 API 结果,哪里setContext更不可能(并且可以说 API 调用可以更好地定位,因为关注点分离问题)?
好吧,将商店放在您的上下文中。
例如,对于可写存储:
<script>
import { getContext } from 'svelte'
const userData = getContext('userData')
function handleRegistration(e) {
doSuperApiCall()
.then(data => {
userData.set(data)
// or fancy:
$userData = data
})
.catch(...)
}
</script>
...
Run Code Online (Sandbox Code Playgroud)
在一些更高的包装组件(例如<App>)的初始化期间将此存储置于上下文中:
<script>
import { setContext } from 'svelte'
import { writable } from 'svelte/store'
const userData = writable(null)
setContext('userData', userData)
</script>
<slot />
Run Code Online (Sandbox Code Playgroud)
通过这种方式,您可以getContext从 (say) 的任何子组件轻松访问您的商店<App>,并异步读取/写入它。
| 归档时间: |
|
| 查看次数: |
805 次 |
| 最近记录: |