【问题标题】:fetch rest api in svelte onmount is happening after the screen is rendered在屏幕渲染后发生在 svelte onmount 中的 fetch rest api
【发布时间】:2021-07-22 15:19:55
【问题描述】:

使用 svelte 文档中的 onMount 照片示例,我可以使用自己的 rest api(又一个 todo ..)来显示数据。我将其更改为将照片 html 放在单独的组件中,并且可以正常工作。这里是 App.svelte

    <script>
        import { onMount } from 'svelte'
        import Photos from './Photos.svelte'
    
        let photos = []
    
        onMount(async () => {
            const res = await fetch('http:///mint20-loopback4:3000/todos');
            photos = await res.json();
            console.log('todolist : ', photos)
        })
    </script>
    
    <Photos bind:photos={photos}/>

然后我学习了 MDN svelte 教程并完成了该教程。后来,我从 store 中删除了 todo 初始列表,并在 App.svelte 中添加了一个 onMount fetch。结果是一个空的待办事项列表,但是当我与应用交互时,会显示数据。

这是控制台输出

Todos.svelte with length of :  0 
into TodoStatus.svelte :  Array []
totalTodos :  undefined 
completedTodos :  undefined 
Todos length - mounted :  0 
todolist :  Array(7) [ {…}, {…}, {…}, {…}, {…}, {…}, {…} ]
completed mount :  Array(7) [ {…}, {…}, {…}, {…}, {…}, {…}, {…} ]```

和 App.svelte

<script lang="ts">
    import Todos from './components/Todos.svelte'
    import Alert from './components/Alert.svelte'
    import { onMount } from 'svelte'
    import type { TodoType } from './types/todo.type'
    
    let initialTodos: TodoType[] = []
    
    onMount(async () => {
        const res = await fetch('http:///mint20-loopback4:3000/todos');
        const json = await res.json();
        console.log('todolist : ', json)
        json.forEach(element  => {
          let t: TodoType = { id: 0, title: '0', isComplete: true }
          t.id = element.id
          t.title = element.title
          if (element.isComplete === undefined) {
            t.isComplete = false
          }
          else {
            t.isComplete = element.isComplete
          }
          initialTodos.push(t)
        })
        console.log('completed mount : ', initialTodos)
   })
</script>
      
 <Alert />
 <Todos bind:todos={initialTodos} />

所以它在照片示例中按预期执行,但不是在这个空数组被传递而不是在 onMount 之前。 todo 示例的组件比只有单个组件的照片多得多,但可以说,我很困惑。我必须做什么才能让初始屏幕使用填充的数据?

只是补充一下——我在照片中加入了控制台登录,它也有相同的模式——第一个子组件日志,最后是 App.svelte 中的 onMount。然而在这里,数据是正确显示的。

所以我认为应该发生的是,因为对数组的更改会动态反映在显示中,当数组更新时,显示也是如此。但在 todos 中并没有发生这种情况。

【问题讨论】:

    标签: svelte-3


    【解决方案1】:

    DOM 仅在变量 assignments 上更新。在您的示例中,您使用 .push() 方法将对象添加到数组中。因此,您需要在 forEach 循环之后添加它以确保组件获得更新:

    initialTodos = initialTodos;
    

    另一种选择是内联执行此操作。您可以替换:

    initialTodos.push(t)
    

    initialTodos = [...initialTodos,t]
    

    Here 是这方面的官方文档。

    【讨论】:

    • 有意义且有效。太棒了 - 非常感谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-24
    • 2020-11-23
    • 1970-01-01
    • 1970-01-01
    • 2021-10-04
    • 2019-12-24
    相关资源
    最近更新 更多