【问题标题】:How to hold off rendering until ajax call completes如何推迟渲染直到 ajax 调用完成
【发布时间】:2019-10-11 11:11:31
【问题描述】:

我正在重构一个从服务器上的 json 文件加载语言标签的 React 应用程序。使用 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 变量的权限,也没有在解析 fetch 调用时更新它。这是错误消息。

Uncaught ReferenceError: Cannot access 'LABELS' before initialization

我在 React 中解决这个问题的方法是仅在从服务器获取语言标签之后渲染整个 &lt;App /&gt;。我还没想出用 Svelte 解决这个问题的方法。

请指教。

解决方案

按照@tehshrike 的建议,我将getLang 设置为异步函数,并在App.svelte 组件上使用await 块,这是应用程序的入口点。这样,当 Promise 在获得语言标签后解决时,App 就会呈现(代码为了便于说明而缩写)。

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}

【问题讨论】:

    标签: svelte svelte-store


    【解决方案1】:

    如果您将您的承诺放入存储本身,而不是等待承诺解决后再将值放入存储中,您可以使用 await block 并引用 $storeLang.labels 而无需在内部设置响应式声明你的组件。

    【讨论】:

    • 感谢您的回答。你能给我一个代码示例吗?我想我已经在商店里有 api 调用。除非您的意思是将 api 调用移至 store 属性,但我仍然需要更多信息来了解我将如何实现这一点。
    • 我明白了你在推荐中的意思。我将使用解决方案编辑问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多