-
-
Notifications
You must be signed in to change notification settings - Fork 109
/
Copy pathlazy.js
43 lines (39 loc) · 1.14 KB
/
lazy.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import { h, options } from 'preact';
import { useState, useRef } from 'preact/hooks';
export default function lazy(load) {
let p, c;
return props => {
const [, update] = useState(0);
const r = useRef(c);
if (!p) p = load().then(m => (c = (m && m.default) || m));
if (c !== undefined) return h(c, props);
if (!r.current) r.current = p.then(() => update(1));
throw p;
};
}
// See https://github.com/preactjs/preact/blob/88680e91ec0d5fc29d38554a3e122b10824636b6/compat/src/suspense.js#L5
const oldCatchError = options.__e;
options.__e = (err, newVNode, oldVNode) => {
if (err && err.then) {
let v = newVNode;
while ((v = v.__)) {
if (v.__c && v.__c.__c) {
if (newVNode.__e == null) {
newVNode.__e = oldVNode.__e; // ._dom
newVNode.__k = oldVNode.__k; // ._children
}
if (!newVNode.__k) newVNode.__k = [];
return v.__c.__c(err, newVNode);
}
}
}
if (oldCatchError) oldCatchError(err, newVNode, oldVNode);
};
export function ErrorBoundary(props) {
this.__c = childDidSuspend;
this.componentDidCatch = props.onError;
return props.children;
}
function childDidSuspend(err) {
err.then(() => this.forceUpdate());
}