setContext
должен вызываться синхронно во время инициализации компонента. То есть из root тега <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>
Это упоминается в небольшом предложении crypti c в документах :
Как и функции жизненного цикла, его необходимо вызывать во время инициализации компонента.
Другими функциями жизненного цикла являются onMount
, onDestroy
, et c. Возможно, менее очевидно, что setContext
- это такой метод жизненного цикла.
Редактировать
Я просто перечитал ваш вопрос и понял, что на самом деле просто отвечаю на половину. ..
setContext
/ getContext
можно использовать только один раз в компоненте init, так как вы делитесь результатами API через контекст? Связанный: как бы вы поделились этими результатами API, если вызов был сделан вне компонента Svelte, где 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>
...
Поместите это хранилище в контекст во время инициация какого-либо более высокого компонента упаковки (например, <App>
):
<script>
import { setContext } from 'svelte'
import { writable } from 'svelte/store'
const userData = writable(null)
setContext('userData', userData)
</script>
<slot />
Таким образом, вы можете легко получить доступ к своему магазину с помощью getContext
из любого дочернего компонента (скажем) <App>
, и читать / писать из него асинхронно.