Instantly share code, notes, and snippets.

Embed
What would you like to do?
A react component that renders a dojo widget.
import React, { Component } from "react";
import PropTypes from "prop-types";
import loader from "@episerver/amd-loader-proxy";
import makeCancelable from "./make-cancelable";
class DojoWidget extends Component {
constructor(props) {
super(props);
this.domNode = React.createRef();
this.state = {
promise: makeCancelable(loader(this.props.type)),
widget: null
};
}
render() {
return <div ref={this.domNode} />;
}
shouldComponentUpdate() {
return false;
}
componentDidMount() {
const { promise } = this.state;
promise.then(([Widget]) => {
const widget = new Widget({ style: this.props.style, ...this.props.settings }, this.domNode.current);
widget.startup();
Object.keys(this.props)
.filter((key) => /^on/.test(key))
.forEach((key) => {
const event = key.replace(/^on/, "").toLowerCase();
widget.on(event, this.props[key]);
});
this.setState({ widget });
});
}
componentWillUnmount() {
const { promise, widget } = this.state;
promise.cancel();
if (widget) {
const { parentNode } = widget.domNode;
widget.destroyRecursive();
// React doesn't like us removing DOM nodes so we add the ref back after the widget has been destroyed.
parentNode.appendChild(this.domNode.current);
}
}
}
DojoWidget.propTypes = {
settings: PropTypes.object,
style: PropTypes.object,
type: PropTypes.string.isRequired
};
export default DojoWidget;
const makeCancelable = (promise) => {
let cancel = () => {};
const wrappedPromise = new Promise((resolve, reject) => {
cancel = () => {
resolve = null;
reject = null;
};
promise.then(
(val) => {
if (resolve) {
resolve(val);
}
},
(error) => {
if (reject) {
reject(error);
}
}
);
});
wrappedPromise.cancel = cancel;
return wrappedPromise;
};
export default makeCancelable;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment