Preserve identity and choose form scope
Compare identity, guarded rendering and two form scopes in one interactive view.
Table of contents
APIs used
- mount
- Starts a Valyrian.js application on a DOM target.
- FormStore
- Coordinates form state, validation, transforms and submission.
Run this recipe
- Starting project
- Use the local TSX and ESM project from Stage 1 with Valyrian.js installed and its ESM browser build configured.
- File
- Replace src/client-entry.tsx with this recipe snippet.
- Run
- Run npm run build, serve public with npx --yes serve@14.2.5 public --listen 8000, open http://localhost:8000 and use the example's visible controls.
- Observable result
- The reordered rows keep their key values, the changed v-keep guard renders the selected profile and each field updates its chosen state object.
Starting point
Start with rows identified by stable ids, one selected profile, a local filter and a FormStore field.
Steps
Reverse the rows, select a different profile and edit each form through its matching state layer.
tsximport { mount } from "valyrian.js";
import { FormStore } from "valyrian.js/forms";
type Row = { id: string; name: string };
const rows: Row[] = [
{ id: "arya", name: "Arya" },
{ id: "sam", name: "Sam" },
];
const localFilter = { query: "" };
const profileForm = new FormStore({
state: { email: "" },
schema: {
type: "object",
properties: { email: { type: "string", format: "email" } },
required: ["email"],
},
onSubmit: async () => {},
});
const RenderingChoices = {
selectedId: "arya",
reverseRows() {
rows.reverse();
},
selectProfile(id: string) {
this.selectedId = id;
},
view() {
const selected = rows.find((row) => row.id === this.selectedId) || rows[0];
return (
<main>
<button onclick={() => this.reverseRows()}>Reverse rows</button>
<ul v-for={rows}>
{(row: Row) => (
<li key={row.id}>
<button onclick={() => this.selectProfile(row.id)}>
{row.name}
</button>
</li>
)}
</ul>
<section v-keep={this.selectedId}>
Selected profile: {selected.name}
</section>
<label>
Local filter
<input name="query" v-model={localFilter} />
</label>
<form v-form={profileForm}>
<label>
Validated email
<input name="email" type="email" v-field={profileForm} />
</label>
<button type="submit">Save profile</button>
</form>
</main>
);
},
};
mount("body", RenderingChoices);Result
The reordered rows keep their key values, the changed v-keep guard renders the selected profile and each field updates its chosen state object.
Limits
Keep keys stable. Change a v-keep guard whenever the guarded subtree input must render again.