한테로
한테로

Reputation: 23

Data prop responsiveness issue when input bind:value in Svelt

When export let data is an object, there is a data prop reactivity problem when using input bind:value.

For example, in the following case

<script>
export let data = {name:"jack", age:31};
$: man = data;
</script>
<input type='text' bind:value={man.name} >
<h1>{data.name}</h1>
<h1>{man.name}</h1>

//input typing jhon
//data.name => jhon
//man.name => jhon

When the bare value of the input changes, the value of the data also changes at the same time. I think it's because of shallow copying.

So, in the case below where deep copy is performed,

<script>
export let data = {name:"jack", age:31};
$: man = structuredClone(data);
</script>
<input type='text' bind:value={man.name} >
<h1>{data.name}</h1>
<h1>{man.name}</h1>

//input typing impossible

Input values ​​cannot be changed.

Ultimately, what I want is for only the value of man to change depending on the input value. (So ​​that the data value does not change)

What am I misunderstanding?

Thank you for reading my post.

<script>
let data = {name:"jack", age:31};
$: man = data;
</script>
<input type='text' bind:value={man.name} >
<h1>{data.name}</h1>
<h1>{man.name}</h1>

//input typing jhon
//data.name => jack
//man.name => jhon

In the case of let data, it does what I want, but I have to use export let data. There is also a way to use $page.data, but more than anything, I want to understand how the above behavior occurs. I would appreciate it if someone could explain.

Upvotes: 0

Views: 64

Answers (1)

chmin.seo
chmin.seo

Reputation: 315

The reactive statement($:...) keeps overwriting variable man whenever man.name is updated fby bind:value...

//[code-01]
export let data = {name:"jack", age:31};
$: man = Object.assign({},data);
  • Both man and data are exposed to be monitored

When typing input field, man.name is updated, which triggers variable man to be reset by the reactive statement($:...).

To avoid it, variable man should be removed from the reactive statement([code-01]).

<script>
export let data = {name:"jack", age:31};
// (1)
let man 
// (2)
const clone = (src) => man = structuredClone(src)
// (3)
$: clone(data)
</script>

<input type='text' bind:value={man.name} >
<h1>data value: {data.name}</h1>
<h1>man value: {man.name}</h1>
  1. declare variable man
  2. declare function to clone the data
  3. variable data is exposed to be monitored

man.name is preserved whenever bind:value... changes the text.

code

ReactiveInput.svelte

<script>
export let data = {name:"jack", age:31};
let man
const clone = (src) => man = structuredClone(src)
    
$: clone(data)
</script>
<input type='text' bind:value={man.name} >
<h1>data value: {data.name}</h1>
<h1>man value: {man.name}</h1>

App.svelte

<script>
import ReactiveInput from "./ReactiveInput.svelte"  
const jack = {name: 'jack', age: 31};
const tom = {name: 'Tom', age: 24};
const mark = {name: 'Mark', age: 43};
const persons = [jack, tom, mark]
let idx = 0;
    
const changePerson = () => {
    idx = (idx + 1) % persons.length 
}
</script>

<ReactiveInput data={persons[idx]}></ReactiveInput>
<button on:click={changePerson}>change</button>

Upvotes: 0

Related Questions