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.
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);
man
and data
are exposed to be monitoredWhen 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>
man
data
is exposed to be monitoredman.name
is preserved whenever bind:value...
changes the text.
<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>
<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>