application/components/layout/root.js
import React from 'react';
import uuid from 'uuid';
import Immutable from 'immutable';
import Events from './../../util/events';
/**
* The idea here is you generate a unique ID and a component
* then emit an addRootComponent event with the id and component
* and it is injected here.
*
* It's really quite hacky but it works. Something like:
*
* <code>
* const myComponent = <SomeThing />;
* events.emit('addRootComponent', myId, myComponent);
*
* // then to remove
* events.emit('removeRootComponent', myId);
* </code>
*/
class RootExtension extends React.Component {
constructor(props) {
super(props);
this.state = {
components: []
}
}
componentWillMount() {
Events.listen('addRootComponent', this.onAdd.bind(this));
Events.listen('removeRootComponent', this.onRemove.bind(this));
}
componentWillUnmount() {
Events.unlisten('addRootComponent', this.onAdd.bind(this));
Events.unlisten('removeRootComponent', this.onRemove.bind(this));
}
onAdd(id, component, callback) {
let components = this.state.components;
for (let comp in components) {
if (components[comp].uuid === id) {
return;
}
}
components.push({'component': component, 'uuid': id});
this.setState({'components': components});
if (callback) {
callback(id);
}
}
onRemove(id) {
let components = this.state.components;
let newComponents = [];
for (let comp in components) {
if (components[comp].uuid === id) {
continue;
}
newComponents.push(components[comp]);
}
this.setState({'components': newComponents});
}
render() {
return (
<div>
{this.state.components.map((child, i) => {
return <div key={child.uuid}>{child.component}</div>;
})}
</div>
);
}
}
export default RootExtension;