Как задержать рендеринг до завершения вызова ajax
Я выполняю рефакторинг приложения React, которое загружает языковые метки из файла json на сервере. Данные извлекаются с сервера с помощью вызова Ajax, который обновляет хранилище, содержащее все языковые метки. Вот некоторый код, иллюстрирующий проблему.
app.js
<script>
import { storeLang, getLangLabels } from './store'
// get labels from server
getLangLabels()
// set language labels in a reactive variable
$: LABELS = $storeLang.labels
</script>
<div>
<h2>{LABELS.title}</h2>
</div>
Вот как настроен магазин. Вызов ajax обновляет магазин с метками.
store.js
import { writeable } from 'svelte/store'
export const storeLang = writeable({})
export const getLangLabels = () => {
return fetch('lang.json').then( data => {
storeLang.set(data);
})
}
Однако, когда я запускаю приложение, у меня еще нет доступа к переменной LABELS, и она не обновляется после разрешения вызова выборки. Вот сообщение об ошибке.
Uncaught ReferenceError: Cannot access 'LABELS' before initialization
Я решил эту проблему в React, чтобы сделать <App />
только после того, как языковые метки были получены с сервера. Я не нашел способ решить эту проблему с помощью Svelte.
Пожалуйста, порекомендуйте.
Решение
Следуя рекомендации @tehshrike, я настроил getLang
в качестве асинхронной функции и использования блока ожидания на App.svelte
компонент, который является точкой входа в приложение. Таким образом, когда обещание разрешается после получения языковых меток, приложение выполняет визуализацию (код, сокращенный в целях иллюстрации).
App.svelte
<script>
import { getLang } from './lang/store.js';
let promise = getLang();
</script>
{#await promise}
Loading language labels
{:then value}
// we don't use the returned value because the labels are stored in
// the store and the subscribed components react accordingly
<Header />
<Sidebar />
<Main />
{:catch}
Error resolving promise
{/await}
1 ответ
Если вы поместили свое обещание в само хранилище, вместо того, чтобы ждать выполнения обещания перед тем, как поместить значение в хранилище, вы можете использовать блок ожидания и ссылку $storeLang.labels
без необходимости устанавливать реактивное объявление внутри вашего компонента.