react-append-to-body
Version:
Higher order react component that appends components outside of the main applications DOM
166 lines (137 loc) • 4.02 kB
Markdown
[](https://travis-ci.org/jpgorman/react-append-to-body)
[](https://badge.fury.io/js/react-append-to-body)
# React higher order component append to body
[React] Higher order component that allows you to attach components to the DOM outside of the main app. Supports __React 16__ and __React 15__ and less, so works with and without ReactDOM.createPortal.
[react]: https://facebook.github.io/react/
# Installation
```sh
npm i react-append-to-body --save
```
# Use
```js
import { componentWillAppendToBody } from "react-append-to-body";
/* Some component that you want to attach to the DOM */
function MyComponent({ children }) {
return <div className="myClassName">{children}</div>;
}
const AppendedMyComponent = componentWillAppendToBody(MyComponent);
class MyApp extends React.Component {
render() {
return (
<div>
// this content will be rendered in the main app Some content on my page
// this content will be rendered outside of the main app
<AppendedMyComponent>
The content for my appended component
</AppendedMyComponent>
</div>
);
}
}
```
```html
/* template */
<html lang="en">
<head>
<meta charset="utf-8">
<meta content="width=device-width,initial-scale=1" name="viewport">
</head>
<body class="body">
<div id="my-app"></div>
<script src="/app.js"></script>
</html>
```
```html
/* output */
<html lang="en">
<head>
<meta charset="utf-8">
<meta content="width=device-width,initial-scale=1" name="viewport">
</head>
<body class="body">
<div id="my-app">
<div>
// this content will be rendered in the main app
Some content on my page
</div>
</div>
<div id="append-element-container">
<div class="myClassName">
The content for my appended component
</div>
</div>
<script src="/app.js"></script>
</html>
```
### Appending to a named DOM node
```js
const AppendedMyComponent = componentWillAppendToBody(MyComponent);
class MyApp extends React.Component {
render() {
return (
<div>
Some content on my page // this content will be rendered in the main app
<AppendedMyComponent
subtreeContainer={"#my-named-element-to-append-with"}
>
The content for my appended component
</AppendedMyComponent> // this content will be rendered outside of the main
app
</div>
);
}
}
```
```html
/* template */
<html lang="en">
<head>
<meta charset="utf-8">
<meta content="width=device-width,initial-scale=1" name="viewport">
</head>
<body class="body">
<div id="my-app"></div>
/* dom node that content will be appended to */
<div id="my-named-element-to-append-with"></div>
<script src="/app.js"></script>
</html>
```
```html
/* output */
<html lang="en">
<head>
<meta charset="utf-8">
<meta content="width=device-width,initial-scale=1" name="viewport">
</head>
<body class="body">
<div id="my-app">
<div>
// this content will be rendered in the main app
Some content on my page
</div>
</div>
<div id="my-named-element-to-append-with">
<div class="myClassName">
The content for my appended component
</div>
</div>
<script src="/app.js"></script>
</html>
```
### With Context
If you want to persist Context into the appended component you can do this by simple setting the contextTypes on the appended component.
```js
// using React Router
const Modal = componentWillAppendToBody(Modal);
Modal.contextTypes = {
router: React.PropTypes.any.isRequired
};
```
## API
`subtreeContainer` a string that should contain a selector that will work with document.querySelector [MDN]: https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector
## Tests
`npm run test`
# Demo
`npm run demo`
Then open up your browser at http://localhost:8777
See [React] docs for examples for your environment.