Skip to content

Instantly share code, notes, and snippets.

@ximus
Last active October 8, 2018 06:58
Show Gist options
  • Save ximus/8737883c9217d6550457 to your computer and use it in GitHub Desktop.
Save ximus/8737883c9217d6550457 to your computer and use it in GitHub Desktop.
react singleton/portal
import ReactDOM from 'react-dom';
/**
* Mount a component elsewhere than where it is declared in the markup.
*
* example use:
* import portal from 'common-util/reactPortal';
* import MyModal from 'MyModal'
*
* // you must specify the DOM node to mount to by specifying a DOM node factory.
* // It will be run every time the component is mounting.
* // This will always mount at the same point in the dom, acting like a
* // singleton:
* const MyModalElsewhere = portal(MyModal, () => myDomNode);
*
* // or mount at a new location for each instance
* const MyModalElsewhere = portal(MyModal, () => {
* const node = document.createElement('div');
* document.body.appendChild(node);
* return node;
* });
*
* then use the componenent in your markup as you usually would, it will be
* mounted elsewhere in the DOM.
* <MyModalElsewhere ...props />
* <MyModalElsewhere ...props />
*/
export default (component, domNodeFactory) => {
return React.createClass({
displayName: `${component.name}Proxy`,
componentDidMount() {
this.renderTarget();
},
componentDidUpdate() {
this.renderTarget();
},
componentWillUnmount() {
ReactDOM.unmountComponentAtNode(this.targetDomNode);
},
renderTarget() {
const domNode = this.targetDomNode || domNodeFactory();
ReactDOM.render(React.createElement(component, this.props), domNode);
this.targetDomNode = domNode;
},
render() {
return null;
},
});
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment