An open API service indexing awesome lists of open source software.

https://github.com/klarna/remote-frames

Render a subset of the React tree to a different location, from many locations, without having to coordinate them
https://github.com/klarna/remote-frames

iframe in-k portals react react-dom

Last synced: 7 months ago
JSON representation

Render a subset of the React tree to a different location, from many locations, without having to coordinate them

Awesome Lists containing this project

README

          

# Deprecated

No longer being maintained.

# @klarna/remote-frames

[![Build Status](https://travis-ci.org/klarna/remote-frames.svg?branch=master)](https://travis-ci.org/klarna/remote-frames)
[![npm version](https://img.shields.io/npm/v/@klarna/remote-frames.svg)](https://www.npmjs.com/package/@klarna/remote-frames)

Render a subset of the React tree to a different location, from many locations, without having to coordinate them.

## Usage

Say that you have an HTML with two DOM nodes that you want to render to:

```html


Remote frame




```

…and for some reason, you want elements in the React tree rendered under the `"main-content-node"` to be able to inject elements into the `"dialogs-node"`. The `RemoteFrame` allows you to send this elements to the remote tree (the one under `"dialogs-node"`).

```js
import React, { Component } from 'react'
import { render } from 'react-dom'
import { RemoteFrame, RemoteFramesProvider } from '@klarna/remote-frames'

const Dialog1 = () =>

Lorem ipsum

const Dialog2 = () =>

Dolor sit amet

class App extends Component {
constructor() {
super()

this.state = {
showDialog1: false,
showDialog2: false,
}
}

render() {
const { showDialog1, showDialog2 } = this.state

return {
console.log(
'a new frame was added to the dialogs-node stack',
frameJSX
)
}}
onFrameRemoved={frameJSX => {
console.log(
'a frame was removed from the dialogs-node stack',
frameJSX
)
}}
onNoFrames={lastJSXRemoved => {
console.log(
'all frames have been removed from the stack',
lastJSXRemoved
)
}}>


App that demonstrates remote-frames


this.setState({
showDialog1: !showDialog1
})}>
{showDialog1 ? 'Hide Dialog 1' : 'Show Dialog 1'}

this.setState({
showDialog2: !showDialog1
})}>
{showDialog2 ? 'Hide Dialog 2' : 'Show Dialog 2'}

{showDialog1 &&

}

{showDialog2 &&

}



}
}

render(
,
document.getElementById('main-content-node')
)
```

Whenever you click the "Show" / "Hide" buttons, the dialogs are sent to a React tree under the `"dialogs-node"`, and rendered one at a time. If there was no dialog being shown at the time, then the new dialog is added; if there was a dialog shown already, the new dialog is shown instead, but then if the new dialog is removed, the old dialog is shown again, as in a sort of stack.

State of the elements inside the `RemoteFrame` is preserved, even when unmounted.

### Missing RemoteFramesProvider

If there is no `RemoteFramesProvider` in the tree before the `RemoteFrame`, the content of `RemoteFrame` will just be rendered in place.

### Context

For the React.context to be propagated to the new tree, you have to manually specify what props of the context you want to propagate:

```js
import React, { Component } from 'react'
import { render } from 'react-dom'
import PropTypes from 'prop-types'
import { getContext, withContext } from 'recompose'
import {
RemoteFrame,
RemoteFramesProvider
} from '@klarna/remote-frames'

const Dialog1 = getContext({ content1: PropTypes.string })(({content1}) =>

{content1}


)

const Dialog2 = getContext({ content2: PropTypes.string })(({content2}) =>

{content2}


)

const App = withContext(
{
content1: PropTypes.string,
content2: PropTypes.string,
},
() => ({
content1: 'Hello Dialog 1',
content2: 'Hello Dialog 2',
})
)(() => {
return


App that demonstrates remote-frames


this.setState({
showDialog1: !showDialog1
})}>
{showDialog1 ? 'Hide Dialog 1' : 'Show Dialog 1'}

this.setState({
showDialog2: !showDialog1
})}>
{showDialog2 ? 'Hide Dialog 2' : 'Show Dialog 2'}








})

render(
,
document.getElementById('main-content-node')
)
```

### Callbacks on `RemoteFramesProvider`

Two callbacks are available on `RemoteFramesProvider`:

- `onFrameAdded`: gets called whenever another frame is added to the stack
- `onNoFrames`: gets called whenever all frames are removed from the stack
- `onFrameRemoved`: gets called whenever a frame is removed from the stack

### Passing the `targetDomElement`

The `targetDomElement` used to render the new React tree can be passed directly to the `RemoteFramesProvider` as a prop, or it can be passed as a Promise, allowing you to wait until the targetDomElement is available (for example if it is rendered in another window).

Frames stacked before the `targetDomElement` is available will be queued, so you will not lose any information.

### Wrapping into `wrapperComponent`

The `wrapperComponent` (alongside with `wrapperComponentProps`) used to wrap `GlobalTarget` into HOC (for example if it is needed to wrap everything into `ThemeProvider`, etc.).

```js

```