Skip to content

Commit

Permalink
Use useLayoutEffect for callback
Browse files Browse the repository at this point in the history
  • Loading branch information
tmeasday committed Jul 28, 2022
1 parent 2740d17 commit 049d84c
Showing 1 changed file with 25 additions and 5 deletions.
30 changes: 25 additions & 5 deletions code/renderers/react/src/render.tsx
@@ -1,7 +1,15 @@
// @ts-ignore
import global from 'global';

import React, { Component as ReactComponent, FC, ReactElement, StrictMode, Fragment } from 'react';
import React, {
Component as ReactComponent,
FC,
ReactElement,
StrictMode,
Fragment,
useLayoutEffect,
useRef,
} from 'react';
import ReactDOM, { version as reactDomVersion } from 'react-dom';
import type { Root as ReactRoot } from 'react-dom/client';

Expand All @@ -26,16 +34,28 @@ export const render: ArgsStoryFn<ReactFramework> = (args, context) => {
return <Component {...args} />;
};

const WithCallback: FC<{ callback: () => void; children: ReactElement }> = ({
callback,
children,
}) => {
// See https://github.com/reactwg/react-18/discussions/5#discussioncomment-2276079
const once = useRef(false);
useLayoutEffect(() => {
if (once.current) return;
once.current = true;
callback();
}, [callback]);

return children;
};

const renderElement = async (node: ReactElement, el: Element) => {
// Create Root Element conditionally for new React 18 Root Api
const root = await getReactRoot(el);

return new Promise((resolve) => {
if (root) {
root.render(node);
setTimeout(() => {
resolve(null);
}, 0);
root.render(<WithCallback callback={() => resolve(null)}>{node}</WithCallback>);
} else {
ReactDOM.render(node, el, () => resolve(null));
}
Expand Down

0 comments on commit 049d84c

Please sign in to comment.