Elderjs/elderjs

Recover component state from DOM

eight04 opened this issue · 1 comments

This is a feature request.

For example, I have a link component:

<script>
import {onMount} from "svelte";
export let url, text;

let linkElement;
onMount(() => {
  // some fancy stuff
})
</script>
<a href={url} bind:this={linkElement}>{text}</a>

To hydrate it, we have to stringify url and text property:

<Link hydrate-client={{link: "http://example.com", text: "Test"}} />

Which produces code like this:

{
  linkABC: {
    component: "Link.blabla.js",
    props: {
      url: "http://example.com",
      text: "Test"
    }
  }
}

However, these props are already available in DOM, result in data duplication.

Proposal

Support "server-only props" via the original syntax:

<Link link="example.com" text="Test" hydrate-client={{}} />

link and text will still be rendered in the server.

Support a recover module function in the component:

<script type="module">
export function recover(node) {
  const a = node.children[0];
  return {url: a.href, text: a.textContent};
}
</script>

<!-- ... other component stuff ... -->

When hydrating:

blabla.then(([comp, props]) => {
  if (comp.recover) {
    Object.assign(props, comp.recover(target));
  }
  new comp.default({ ... })
})

I don't know whether this is already supported by svelte. Is svelte component able to recover its state from pre-rendered DOM?

The example usage in this issue - the template is static and we only want to add js code in onMount - is probably covered by #237