shoverian
shoverian

Reputation: 23

Svelte on:click function updates data, but not UI

I am new to Svelte, so I suspect this is a very fundamental lack-of-understanding issue.

Can someone explain why the on:click updates the UI, but the UI will not update if I attempt to use the changeJob(items)? The console.log indicates all jobs were changed in the array, but the UI does not reflect that.

<script>
  import ListItem from './ListItem.svelte';

  let items = [
    { name: 'John', age: 23, job: 'plumber'},
    { name: 'Jane', age: 45, job: 'hair stylist'},
    { name: 'Juan', age: 18, job: 'student'},
  ];

  const changeJob = (arr) => {
    console.log(arr[0].job);
    arr[0].job = 'clown';
    console.log(arr[0].job);
  }

</script>

<button on:click={() => items[0].job = 'clown'}>Clownify</button>

<ul>
  {#each items as item }
    <ListItem {...item}/>
  {/each}
</ul>

Code snippet: REPL

Upvotes: 2

Views: 932

Answers (1)

Rich Harris
Rich Harris

Reputation: 29585

When you have some code like this...

items[0].job = 'clown'

...Svelte understands that it needs to update anything that depends on items, because the assignment is to a property of something it recognises as a top-level variable inside <script>.

But when you do this...

const changeJob = (arr) => {
  arr[0].job = 'clown';
}

...you're not assigning to a property of a top-level variable, you're assigning to a property of the local arr variable inside the function. It's effectively opaque to Svelte.

It will work if you just get rid of the local variable, like so:

const changeJob = () => {
  items[0].job = 'clown';
}

Upvotes: 4

Related Questions