-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathreact.ts
53 lines (50 loc) · 1.5 KB
/
react.ts
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
44
45
46
47
48
49
50
51
52
53
import {
memo,
useEffect,
useRef,
useState,
type FunctionComponent,
} from 'react';
import { $, isManaged, manage, run, type ManateEvent } from '.';
import TransactionsManager from './transactions';
export const auto = <P extends object>(Component: FunctionComponent<P>) => {
return memo(function MyComponent(props: P) {
// dispose
const disposeFunction = useRef<() => void>();
disposeFunction.current?.();
const dispose = () => {
if (managed) $(managed).dispose();
managed = undefined;
};
disposeFunction.current = dispose;
useEffect(() => {
if (!managed) {
// <StrictMode /> will run useEffect, dispose and re-run useEffect
// eslint-disable-next-line react-hooks/exhaustive-deps
managed = manage(
Object.fromEntries(
Object.entries(props).filter(([, v]) => isManaged(v)),
) as P,
);
$(managed).on(listener);
}
return dispose;
}, []);
// run and refresh
let managed: P | undefined = manage(
Object.fromEntries(
Object.entries(props).filter(([, v]) => isManaged(v)),
) as P,
);
const [result, isTrigger] = run(managed, () => Component(props));
const [, refresh] = useState(0);
const transactionsManager = new TransactionsManager(isTrigger);
const listener = (event: ManateEvent) => {
if (transactionsManager.shouldRun(event)) {
refresh((i) => i + 1);
}
};
$(managed).on(listener);
return result;
});
};