Skip to content

Commit db3fd1b

Browse files
authored
Fix iframe detecting for react devtools if no iframe is loaded or available (codesandbox#2302)
Fixes codesandbox#2300
1 parent 26e3b9f commit db3fd1b

File tree

1 file changed

+34
-14
lines changed
  • packages/app/src/app/components/Preview/DevTools/React-Devtools

1 file changed

+34
-14
lines changed

packages/app/src/app/components/Preview/DevTools/React-Devtools/index.tsx

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import React, { useEffect, useState, useContext } from 'react';
1+
import React, { useEffect, useState, useContext, useCallback } from 'react';
2+
import delay from '@codesandbox/common/lib/utils/delay';
23
import { initialize } from 'react-devtools-inline/frontend';
34
import { dispatch, actions } from 'codesandbox-api';
45
import { ThemeContext } from 'styled-components';
@@ -9,24 +10,43 @@ import { DevToolProps } from '..';
910
const DevTools = (props: DevToolProps) => {
1011
const [ReactDevTools, setDevTools] = useState(null);
1112
const theme = useContext(ThemeContext);
13+
const unmounted = React.useRef(false);
1214

13-
useEffect(() => {
14-
const iframe = document.getElementById(
15+
const loadIframe = useCallback(async () => {
16+
let iframe = document.getElementById(
1517
'sandbox-preview'
1618
) as HTMLIFrameElement;
17-
const contentWindow = iframe.contentWindow;
18-
19-
setDevTools(initialize(contentWindow));
20-
iframe.onload = () => {
21-
contentWindow.postMessage(
22-
{
23-
type: 'activate',
24-
},
25-
'*'
26-
);
27-
};
19+
20+
// iframe hasn't initialized or just isn't there
21+
while (iframe === null && !unmounted.current) {
22+
// Retry every second
23+
// eslint-disable-next-line
24+
await delay(1000);
25+
iframe = document.getElementById('sandbox-preview') as HTMLIFrameElement;
26+
}
27+
28+
if (iframe) {
29+
const contentWindow = iframe.contentWindow;
30+
31+
setDevTools(initialize(contentWindow));
32+
iframe.onload = () => {
33+
contentWindow.postMessage(
34+
{
35+
type: 'activate',
36+
},
37+
'*'
38+
);
39+
};
40+
}
2841
}, []);
2942

43+
useEffect(() => {
44+
loadIframe();
45+
return () => {
46+
unmounted.current = true;
47+
};
48+
}, [loadIframe]);
49+
3050
if (props.hidden) {
3151
return null;
3252
}

0 commit comments

Comments
 (0)