Svelte设置store值后为何首次进入#if块无法读取?
Svelte Store更新与渲染周期问题解析
问题场景
作为Svelte新手,定义了如下简单store:
import { writable } from 'svelte/store'; export let store = writable({});
主应用组件代码:
<script> import {store} from './store.js' async function functionOne() { console.log("functionOne called") } function setStore() { $store = {foo: 'bar'} console.log(`Store is set, equals: ${JSON.stringify($store)}`) return true } </script> <main> {#await functionOne()} Loading... {:then _} {#if setStore()} {console.log(`We are inside the #if block with store=${JSON.stringify($store)}`)} {/if} {/await} </main>
运行后日志输出:
functionOne called Store is set, equals: {"foo": "bar"} We are inside the #if block with store={} We are inside the #if block with store={"foo": "bar"}
疑问:在setStore()中已经设置了store值,为何第一次进入#if块时,store还是初始的空对象,之后又再次执行并显示正确值?
原因解析
这是因为Svelte的渲染更新是批次处理的:
- 当在
setStore()中修改$store时,Svelte不会立即触发组件重渲染,而是把这个更新加入到更新队列,等当前渲染周期完成后再统一处理。 - 第一次执行
#if块内容时,处于当前渲染周期内,组件使用的是渲染开始时的store快照(空对象),所以日志显示{}。 - 当前渲染周期结束后,Svelte处理更新队列里的store变更,触发组件重渲染,此时
#if条件依然为true,再次执行块内代码,这时store已经是更新后的值,所以日志显示正确的{"foo": "bar"}。
简单来说:修改store的操作不会同步影响当前正在进行的渲染流程,要等到下一个渲染批次才会生效。
内容的提问来源于stack exchange,提问作者Cartucho
相关产品推荐
相关产品推荐

