In Svelte, changes to arrays or objects might not update the screen automatically. This happens because Svelte needs to know when data changes to refresh the view.
Array and object reactivity gotchas in Svelte
let items = [1, 2, 3]; // Wrong way: items[0] = 10; // UI might not update // Correct way: items[0] = 10; items = [...items]; // reassign to trigger update let user = { name: 'Alice', age: 25 }; // Wrong way: user.name = 'Bob'; // UI might not update // Correct way: user = { ...user, name: 'Bob' }; // reassign to trigger update
Svelte tracks changes by assignments. Directly changing array elements or object properties does not count as an assignment.
To update arrays or objects reactively, you must reassign the whole array or object.
let numbers = [1, 2, 3]; numbers[0] = 10; // UI might not update // Fix: numbers = [...numbers];
let colors = []; colors.push('red'); // UI might not update // Fix: colors = [...colors];
let profile = { name: 'Sam', age: 30 }; profile.age = 31; // UI might not update // Fix: profile = { ...profile, age: 31 };
let emptyObj = {}; emptyObj.newProp = 'value'; // UI might not update // Fix: emptyObj = { ...emptyObj, newProp: 'value' };
This Svelte component shows a list of fruits and user info. Buttons update the array and object. Without reassigning, the UI won't refresh. Using spread syntax to create new copies triggers Svelte's reactivity.
<script> let fruits = ['apple', 'banana', 'cherry']; let user = { name: 'Anna', city: 'Paris' }; function updateFirstFruit() { fruits[0] = 'apricot'; // This alone won't update the UI fruits = [...fruits]; // Reassign to trigger update } function addFruit() { fruits.push('date'); // This alone won't update the UI fruits = [...fruits]; // Reassign to trigger update } function changeUserCity() { user.city = 'London'; // This alone won't update the UI user = { ...user }; // Reassign to trigger update } </script> <h2>Fruits:</h2> <ul> {#each fruits as fruit} <li>{fruit}</li> {/each} </ul> <button on:click={updateFirstFruit}>Change first fruit</button> <button on:click={addFruit}>Add fruit</button> <h2>User Info:</h2> <p>Name: {user.name}</p> <p>City: {user.city}</p> <button on:click={changeUserCity}>Change city</button>
Time complexity: Reassigning arrays or objects copies data, so large data can be slower.
Space complexity: Creating new copies uses extra memory temporarily.
Common mistake: Changing array elements or object properties directly without reassigning.
Use this approach whenever you want Svelte to notice changes inside arrays or objects.
Svelte updates the UI only when you assign new values to variables.
Direct changes inside arrays or objects do not trigger updates.
Always reassign arrays or objects using spread syntax to make changes reactive.
Practice
arr[0] = 10 not update the UI?Solution
Step 1: Understand Svelte's reactivity model
Svelte updates the UI only when a variable is assigned a new value, not when its internal parts change.Step 2: Analyze direct array element modification
Changingarr[0] = 10mutates the array but does not assign a new array toarr, so Svelte does not detect the change.Final Answer:
Because Svelte only tracks assignments to the whole variable, not internal mutations. -> Option DQuick Check:
Direct mutation ≠ UI update [OK]
- Thinking direct mutations trigger updates
- Believing arrays are immutable in Svelte
- Using methods without reassignment
Solution
Step 1: Recall Svelte's reactivity for objects
Svelte detects changes only when the whole object variable is reassigned.Step 2: Evaluate each option
obj = { ...obj, key: 'value' };uses spread syntax to create a new object and assign it toobj, triggering reactivity. Direct property assignment likeobj.key = 'value';orObject.assign(obj, { key: 'value' });mutate the object without reassignment, andobj.key = 'value'; obj.update();calls a non-existent method.Final Answer:
obj = { ...obj, key: 'value' }; -> Option AQuick Check:
Reassign object with spread = reactive update [OK]
- Mutating object properties directly
- Expecting methods like obj.update() to exist
- Using Object.assign without reassignment
let numbers = [1, 2, 3]; numbers.push(4);
What will Svelte render if you display
{numbers.join(',')} immediately after?Solution
Step 1: Understand array mutation with push()
Thepush()method changes the array but does not reassign it.Step 2: Check Svelte's reactivity trigger
Sincenumbersis not reassigned, Svelte does not detect the change and the UI remains with the old array.Final Answer:
1,2,3 -> Option BQuick Check:
Array mutation without reassignment = no UI update [OK]
- Assuming push triggers UI update
- Expecting automatic reactivity on mutations
- Confusing errors with silent no-update
let user = { name: 'Alice', age: 25 };
function birthday() {
user.age += 1;
}Why does calling
birthday() not update the UI showing {user.age}?Solution
Step 1: Analyze mutation inside birthday()
The function incrementsuser.agedirectly, mutating the object.Step 2: Check reactivity requirements
Svelte requires reassignment of the whole object variable to detect changes; direct mutation alone does not trigger UI updates.Final Answer:
Because the function does not reassign the user object after mutation. -> Option CQuick Check:
Direct mutation without reassignment = no UI update [OK]
- Thinking numeric properties are special
- Assuming await is needed for sync code
- Believing direct mutation triggers UI update
items reactively in Svelte?Solution
Step 1: Understand reactivity with arrays
Direct mutation likeitems[0] = 'new'does not trigger updates unless followed by reassignment.Step 2: Evaluate each option
items = ['new', ...items.slice(1)]; creates a new array with the first element replaced, triggering reactivity correctly. items = [...items]; items[0] = 'new'; creates a shallow copy of the array first, then mutates the first element, which is reactive because the reassignment happens before mutation and the array reference changes. items[0] = 'new'; items = items; mutates first then reassigns the same array reference, which may not trigger reactivity reliably. items = items; items[0] = 'new'; reassigns the same array reference then mutates, which does not trigger reactivity.Final Answer:
items = [...items]; items[0] = 'new'; -> Option AQuick Check:
Reassign array with spread then mutate = reactive update [OK]
- Mutating after reassignment
- Reassigning without changes
- Mutating before reassignment expecting update
Ready to prove it?
Pass the test and this pattern moves unknown
