React to route change.

huangapple go评论113阅读模式
英文:

React to route change

问题

我正在尝试使用Svelte Kit构建Web应用程序。我有以下路由结构:

  • [roleId]
    • +layout.ts
    • +page.svelte

+layout.ts包括一个从服务器获取数据的load函数。
+page.svelte使用export let data: PageData;来消耗获取的数据。

我可以成功地显示并编辑角色名称,使用以下代码:

export let data: PageData;
let roleName: string = data.role.name;
...
<TextInput bind:value={roleName} />

但是,当我通过点击链接更改URL(例如,从"/roles/1"到"/roles/2")时,它不会将角色名称更新为新角色。

我尝试使用以下代码来对获取的数据的更改做出反应:

export let data: PageData;
$: roleName = data.role.name;
...
<TextInput bind:value={roleName} />

它解决了在单击链接时不更新角色名称的问题,但引入了一个问题,即我无法通过更新TextInput中的值来更改roleName。

据我了解,$: 语法用于创建一个响应式语句,这意味着每当它的任何依赖项发生更改时都会重新评估。但为什么它会在roleName更改时触发重新评估呢?

当将以下代码添加到第二个示例中时:
$: console.log(data.role.name);
它在每次键盘输入时都会在控制台上记录相同的角色名称。

英文:

I am trying to build a Web-Application using svelte kit. I got the following route structure:

  • [roleId]
    • +layout.ts
    • +page.svelte

The +layout.ts includes a load function that fetches the data from the server.
The +page.svelte consumes the fetched data using export let data: PageData;.

I can successfully display and edit a role name with this code:

export let data: PageData;
let roleName: string = data.role.name;
...
&lt;TextInput bind:value={roleName} /&gt;

But when i am changing the url, by clicking on a link (e.g. from "/roles/1" to "roles/2"), it does not update the role name to the new role.

I tried this code to react to an change on the fetched data:

export let data: PageData;
$: roleName = data.role.name;
...
&lt;TextInput bind:value={roleName} /&gt;

And it solves the problem of the not updating the role name on a link click, but it introduces the problem that i cannot change the roleName by updating the value in the TextInput.

As far as i understood the $: syntax, it is used to create a reactive statement, which means that it will be re-evaluated whenever any of its dependencies change.
But why is it triggering a re-evaluation when the roleName changes?

When adding following code to the second example:
$: console.log(data.role.name);
It logs the same role name on every keyboard input to the console.

答案1

得分: 0

这是一个关于依赖跟踪的怪异现象/潜在bug,与SvelteKit无关。

bind:value 会导致在输入时使 data 无效,从而导致重置,可能是因为响应式语句在 roleNamedata 之间创建了关系,尽管它应该是从 dataroleName 的单向关系。

您可能可以通过不使用 bind,将其拆分为输入和事件来解决这个问题:

<TextInput value={roleName} on:input={e => roleName = e.target.value} />

(这需要组件提供相应的事件,通常是从某个常规的 <input> 转发的。)

英文:

This is an oddity/potential bug in how dependencies are tracked and not specific to SvelteKit.

The bind:value will cause data to be invalidated on input, causing a reset, presumably because the reactive statement creates a relationship between roleName and data, even though it is supposed to be one-way from data to roleName.

You probably can work around this by not using bind and splitting it into input and event:

&lt;TextInput value={roleName} on:input={e =&gt; roleName = e.target.value} /&gt;

(This requires the component to provide the respective event, usually forwarded from some regular &lt;input&gt;.)

huangapple
  • 本文由 发表于 2023年3月7日 04:57:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/75655792.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定