Skip to content

Instantly share code, notes, and snippets.

View developit's full-sized avatar
🦊
write, the codes

Jason Miller developit

🦊
write, the codes
View GitHub Profile
import ReactDOM from "react-dom";
import { RemixBrowser } from "remix";
// hydrate a fake Document with the patch:
ReactDOM.hydrate(<RemixBrowser />, {
childNodes: [document.documentElement],
firstChild: document.documentElement,
appendChild(n) { document.replaceChild(n, document.documentElement); },
insertBefore(n) { this.appendChild(n); }
});
import { h, hydrate } from 'preact';
let C = 0;
export function Root({ href, data, children }) {
let json = data && JSON.stringify(data);
let id = 'root:'+++C;
return [
h(`!--${id}--`),
children,
h('component-root', { href, id },

AsyncComponent for preact

This is the guts of preact-cli's import X from 'async!./x' feature, extracted into a standalone library.

It creates a wrapper component that, when rendered, lazy-loads your real component. While loading, any SSR'd DOM is preserved intact.

Option 1: lazy()

This is the API of React.lazy() or preact-iso's lazy(), but it does not use Suspense.

Rendering Interactive HTML using Preact

It's possible to render HTML in Preact using the dangerouslySetInnerHTML prop, however doing so bypasses the Virtual DOM entirely. This may be reasonable for static HTML, but interactivity can be a little painful to graft on without VDOM.

There is another technique available that melds HTML to Virtual DOM without such limitations.

Enter DOMParser

Horrible JSX Transform

import { jsx } from './jsx.js';

const out = jsx(`
  const App = props => (
    <div class="app">
      <h1>Hello {"World"}</h1>
      <ul>{['a','b','c'].map(item => <li>{item}</li>)}</ul>
import { options } from 'preact';
// Fix Preact rendering when Google Translate breaks the DOM
const FONT_AS_TEXT = {
localName: {
value: null
},
nodeType: {
value: 3
},
/**
* Usage:
* class FancyButton extends HTMLElement {
* constructor() {
* super();
* ensureShadowRoot(el);
* // if a declarative shadow root was present, it'll be here:
* console.log(this.shadowRoot);
* }
* }
if (!Element.prototype.getInnerHTML) {
Element.prototype.getInnerHTML = function(opts) {
var html = this.innerHTML;
if (!opts || !opts.includeShadowRoots) return html;
var m = new (self.WeakMap || Map)();
for (var c of (opts.closedRoots || [])) m.set(c.host, c);
var p = [];
function walk(node) {
var c, shadow = node.shadowRoot || m.get(node);
if (shadow) p.push(node.innerHTML, `<template shadowroot="${shadow.mode}">${shadow.innerHTML}</template>`);
/**
* cloneNode(true), but also clones shadow roots.
* @param {Element}
* @param {ShadowRoot[]} [shadowRoots] Any closed shadow roots passed here will be included.
*/
function cloneWithShadowRoots(node, shadowRoots) {
function walk(node, clone) {
let shadow = node.shadowRoot || shadowRoots.find(r => r.host === node);
if (shadow) {
clone.attachShadow({ mode: shadow.mode }).append(...[].map.call(shadow.childNodes, c => c.cloneNode(true)));

Preact: Progressive Hydration

Preact now supports seamless progressive hydration.

Any component can throw during hydration (or new tree creation like a route change!), and if a component somewhere higher in the tree catches that via componentDidCatch, hydration gets paused.

Re-rendering the tree (via setState, etc) simply resumes hydration where it left off.