Skip to content

Commit

Permalink
[gem] Add react shim
Browse files Browse the repository at this point in the history
Closed #147
  • Loading branch information
mantou132 committed Apr 20, 2024
1 parent f2fd2c5 commit f147730
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 6 deletions.
5 changes: 3 additions & 2 deletions packages/gem/src/dist.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ export * from './elements/reflect';
export * from './elements/base/modal-factory';
export * from './elements/base/dialog';

export * from './helper/theme';
export * from './helper/i18n';
export * from './helper/request';
export * from './helper/logger';
export * from './helper/mediaquery';
export * from './helper/request';
export * from './helper/theme';

export * from '.';
57 changes: 57 additions & 0 deletions packages/gem/src/helper/react-shim.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
import { ReactNode, useEffect, useRef, useState } from 'react';

Check failure on line 3 in packages/gem/src/helper/react-shim.ts

View workflow job for this annotation

GitHub Actions / lint

Unable to resolve path to module 'react'
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
import { Root, createRoot } from 'react-dom/client';

Check failure on line 6 in packages/gem/src/helper/react-shim.ts

View workflow job for this annotation

GitHub Actions / lint

Unable to resolve path to module 'react-dom/client'

import { Store, connect } from '../lib/store';

/**
* `<gem-route>.routes.getContent`
*/
export function renderReactNode(ele: any, node: ReactNode) {
ele.react?.unmount();
ele.react = createRoot(ele);
// async
ele.react.render(node);

// override
const routeEle = ele instanceof HTMLElement ? ele : ele.host;
const originUnmounted = routeEle.unmounted;
if (!originUnmounted?.react) {
routeEle.unmounted = () => {
originUnmounted?.apply(routeEle);
ele.react.unmount();
};
routeEle.unmounted.react = true;
}
}

/**
* Same as `@connectStore`
*/
export function connectStore<T extends object>(store: Store<T>) {
const [_, update] = useState({});
useEffect(() => connect(store, () => update({})), []);
}

/**
* Warning: https://github.com/facebook/react/issues/25675
*/
export function useReactNode(node: ReactNode) {
const ref = useRef<{ root: Root; container: HTMLElement }>();
// Warning: Attempted to synchronously unmount a root while React was already rendering. React cannot finish unmounting the root until the current render has completed, which may lead to a race condition.
useEffect(() => () => ref.current?.root.unmount(), []);
if (ref.current) {
ref.current.root.render(node);
return ref.current.container;
}
const container = document.createElement('div');
container.style.display = 'contents';
const root = createRoot(container);
ref.current = { root, container };
// Warning: Render methods should be a pure function of props and state; triggering nested component updates from render is not allowed. If necessary, trigger nested updates in componentDidUpdate.
root.render(node);
return container;
}
7 changes: 3 additions & 4 deletions packages/gem/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
export * from './lib/store';
export * from './lib/history';
export * from './lib/element';
export * from './lib/decorators';
export * from './lib/element';
export * from './lib/history';
export * from './lib/store';
export * from './lib/utils';

export * from './lib/version';

0 comments on commit f147730

Please sign in to comment.