Svelte中调用update方法无数据变更却始终触发重渲染问题问询
update()? Hey there, let's break this down for you. What you're seeing is expected behavior in Svelte, not an issue with your code or a bug in the framework.
Why this happens
Svelte's store update() method works by notifying all subscribers whenever it's called—regardless of whether the returned value is the same reference or not. Unlike Redux (which does shallow comparisons in selectors by default), Svelte doesn't automatically check if the data has actually changed when you call update() or set(). This design choice is for performance: skipping automatic comparison saves overhead, especially when working with large datasets.
In your example, store.update(s => s) returns the exact same array reference, but since you called update(), Svelte still tells the component to re-render, which triggers your afterUpdate log.
How to avoid unnecessary re-renders
If you want to prevent extra re-renders when the data hasn't changed, you'll need to add your own check before updating the store. Here's how you can adjust your store.js:
import { writable, get } from 'svelte/store' export const store = writable([]) export const updateStore = () => { const currentValue = get(store) // Replace this with your actual update logic // For this example, we're not modifying the data, so we skip the update const newValue = currentValue // Or your modified data // Compare current and new values (adjust based on your data type) // Note: JSON.stringify is a simple solution, but may fail with dates/functions/circular references const hasChanged = JSON.stringify(currentValue) !== JSON.stringify(newValue) if (hasChanged) { store.set(newValue) // Or use store.update if you prefer the callback pattern: // store.update(() => newValue) } }
A few quick notes on comparisons:
- For primitive values (strings, numbers, booleans), a simple
===check works perfectly - For arrays/objects, you might want a custom shallow or deep compare function for more reliability than
JSON.stringify
Recap
- Seeing the 'render' log every click is normal for Svelte's store behavior
- Svelte doesn't auto-validate data changes on store updates—you need to implement that logic yourself if you want to skip unnecessary re-renders
- Using
get(store)to access the current value and comparing it to your intended new value is the standard approach here
内容的提问来源于stack exchange,提问作者Nicolas SEPTIER

