Как задержать рендеринг до завершения вызова ajax - PullRequest
0 голосов
/ 25 мая 2019

Я выполняю рефакторинг приложения 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 в качестве асинхронной функции и с использованием блока await для компонента 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 Ответ

1 голос
/ 25 мая 2019

Если вы положили свое обещание в само хранилище, вместо того, чтобы ждать разрешения обещания перед тем, как поместить значение в хранилище, вы можете использовать блок ожидания и ссылку $storeLang.labels без необходимости устанавливатьдо реактивной декларации внутри вашего компонента.

...