import React , { IframeHTMLAttributes , useEffect , useRef , RefObject } from 'react' ; import { withRouter , RouteComponentProps } from 'react-router' ; import { HostSync , HostSyncInit } from '@ringcentral/web-apps-sync-host' ; import { normalizeHistory } from '@ringcentral/web-apps-react' ; see https export function useCombinedRefs < T > ( ... refs ) { const targetRef = React . useRef < T > ( ) ; useEffect ( ( ) => { refs . forEach ( ref => { if ( ! ref ) return ; if ( typeof ref === 'function' ) { ref ( targetRef . current ) ; } else { ref . current = targetRef . current ; } } ) ; } , [ refs ] ) ; return targetRef ; } export interface IFrameProps extends IframeHTMLAttributes < HTMLIFrameElement > , RouteComponentProps , Pick < HostSyncInit , 'tracking' | 'minHeight' | 'origin' > { nodeRef : any ; url : string ; } see https export const IFrame = withRouter < IFrameProps , any > ( ( { nodeRef , id , url , tracking , minHeight , origin , ... props } ) => { const history = normalizeHistory ( props ) ; const iframe = useRef < HTMLIFrameElement > ( null ) ; const combinedRef = useCombinedRefs < HTMLIFrameElement > ( nodeRef , iframe ) ; useEffect ( ( ) => { const sync = new HostSync ( { id , url , iframe : combinedRef . current , history , tracking , minHeight , origin , } ) ; return ( ) => sync . destroy ( ) ; } , [ combinedRef , history , id , iframe , minHeight , origin , tracking , url ] ) ; delete props [ 'staticContext' ] ; return ( < iframe ref = { combinedRef } src = "" title = "synchronized-iframe" scrolling = "no" frameBorder = "no" { ... props } />); } ) ;