如果父组件在生命周期内更新传递给子组件的prop的值,那么孩子如何在自己的生命周期中使用该prop的最新值?
在下面的示例中,prop值在子组件的生命周期中未定义:
App.svelte
<script>
import { onMount } from 'svelte';
import Nested from './Nested.svelte';
let name;
onMount(() => {
name = "world";
})
</script>
<h1>Hello <Nested name="{name}" /></h1>
Nested.svelte
<script>
import { onMount, afterUpdate } from 'svelte';
export let name;
onMount(() => {
console.log("mount name:", name);
})
afterUpdate(() => {
console.log("after update name:", name);
})
</script>
<span>{name}</span>
https://svelte.dev/repl/65ac3d9c3913408bad459e2ad2a27d8e?version=3.4.2
如果我等待tick
,则生命周期中会提供最新的值,但是我不确定这是否是正确的处理方法:
App.svelte
<script>
import { onMount } from 'svelte';
import Nested from './Nested.svelte';
let name;
onMount(() => {
name = "world";
})
</script>
<h1>Hello <Nested name="{name}" /></h1>
Nested.svelte
<script>
import { onMount, afterUpdate, tick } from 'svelte';
export let name;
onMount(async () => {
await tick();
console.log("mount name:", name);
})
afterUpdate(async () => {
await tick();
console.log("after update name:", name);
})
</script>
<span>{name}</span>
https://svelte.dev/repl/9e66f312a17d41a8adf6e3e3b95c5327?version=3.4.2
答案 0 :(得分:0)
在逻辑上没有人会像您一样在onMount
钩子中同步设置状态 的情况,因为如果您希望它在挂载时就在那里,则应该进行设置在let name = 'world';
一种合理的情况是在onMount
钩中异步地设置状态(例如,发出ajax请求并将ajax响应值设置为状态)。
如果您尝试模拟这样的异步操作
// App.svelte
onMount(() => {
setTimeout(()=>{
name = "world";
},0)
})
无需使用tick()
,一切正常。 afterUpdate
钩子按预期收到更新的值。
https://svelte.dev/repl/9e0411ed66e34e2e8ac1937e41b2709a?version=3.4.2
答案 1 :(得分:0)
TL; DR
如果您需要在子组件的onMount
生命周期方法中专门运行逻辑 ,则将await tick()
添加到该方法–您已经在问题中显示了-这是您唯一的选择。
如果您要这样做,则最好保持一致,并将相同的修订应用于您的afterUpdate
生命周期方法。
完整答案
我怀疑您遇到的问题的一部分可能与this open issue有关,详细说明了有时afterUpdate
并未被调用的方式。
在针对该问题进行修复之前(如果确实有此问题),根据您的要求,有几种方法可以解决当前的问题:
name = "world"
而不是setTimeout(() => name = "world")
afterUpdate
代替使用beforeUpdate
await tick()
添加到您的生命周期方法中,就像您在问题中所显示的那样前两个选项的缺点是,name
在您孩子的onMount
函数中仍然是未定义的–这是因为父母的onMount
被称为 after < / em>孩子的孩子(看起来像是a relatively recent, intentional change)。因此,如果您需要在挂载孩子时专门运行逻辑,那么您会很幸运。
第二个选择的另一个缺点是,顾名思义,beforeUpdate
是在 应用于DOM之前触发的。因此,如果您需要访问更新的DOM,那么您再也没有运气了。
第三个选项没有任何一个问题,但是正如您在原始问题中提到的那样,这有点...奇怪,并且一旦解决了基本问题,它可能会变得有些多余(再次,如果确实,我链接的未解决问题是相关的)。
话虽这么说,无论问题的状态如何,第三个选项都是唯一的选项,使您可以使用孩子的name
方法访问更新后的onMount
。
添加await tick()
起作用的原因是,您最终将孩子的生命周期逻辑推迟到之后应用了最新一批更改。例如,这意味着父级的onMount
生命周期方法将在滴答解决之前 完成,从而允许孩子的onMount
生命周期方法查看{{1 }}。