Как задержать рендеринг до завершения вызова 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 без необходимости устанавливать реактивное объявление внутри вашего компонента.

Другие вопросы по тегам