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' ;
23import { initialize } from 'react-devtools-inline/frontend' ;
34import { dispatch , actions } from 'codesandbox-api' ;
45import { ThemeContext } from 'styled-components' ;
@@ -9,24 +10,43 @@ import { DevToolProps } from '..';
910const 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