Skip to content

Instantly share code, notes, and snippets.

@vadirn
Last active February 9, 2017 07:29
Show Gist options
  • Save vadirn/9783c1196ad0e41fba74b2e36a4a8ae4 to your computer and use it in GitHub Desktop.
Save vadirn/9783c1196ad0e41fba74b2e36a4a8ae4 to your computer and use it in GitHub Desktop.
import React from 'react';
import ReactDOM from 'react-dom';
import ObjectStateStorage from 'object-state-storage';
class Session {
constructor(mountPoint, controllers) {
if (!mountPoint) {
throw new Error('"mountPoint" property is not defined');
}
if (Object.keys(controllers).length === 0) {
throw new Error('"controllers" property cannot be empty');
}
this._mountPoint = mountPoint;
this._controllers = controllers;
this._unmounting = false;
this._store = new ObjectStateStorage({});
// bind!
this.setCurrentController = this.setCurrentController.bind(this);
this._unmount = this._unmount.bind(this);
this._render = this._render.bind(this);
// re-render controller's view on store updates
this._store.subscribe(() => {
if (!this._unmounting) {
this._render();
}
});
}
setCurrentController(name, initialState) {
// get wrapper for require.ensure
const ensureController = this._controllers[name];
if (!ensureController) {
throw new Error(`Controller ${name} not found`);
}
// load controller
// NOTE: failed chunk requests are not handled
ensureController((Controller) => {
// dispose previous controller, if controller exists
if (this._controller) {
this._controller.dispose();
}
// disable re-rendering
this._unmounting = true;
// unmount view
this._unmount();
// create a new controller
// pass Session's actions and context
this._controller = new Controller(initialState, this.context);
// enable re-rendering
this._unmounting = false;
// render new view
this._render();
});
}
_unmount() {
ReactDOM.unmountComponentAtNode(this._mountPoint);
}
_render() {
ReactDOM.render(
React.createElement(this._controller.view),
this._mountPoint,
);
}
// shared context, used in actions
get context() {
return {
store: this._store,
setCurrentController: this.setCurrentController,
};
}
}
export default Session;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment