Ghost/ghost/admin/app/components/react-component.js
Kevin Ansfield a4a4136c2f Fixed hooks not being usable inside of react components
no issue

- switched to using the `window.ReactDOM` instance that is created when importing the react/react-dom libraries
  - React stores state/component references inside of the ReactDOM instance when rendering so we need to make sure all renders use the same instance otherwise it loses track of which component a hook belongs to
- cleaned up unnecessary vendor shims and `prop-types` import
  - `react` and `react-dom` vendor shims are unused when using the globals instead of imports
  - `prop-types` import+shim is not required as it's part of the `@tryghost/koenig-react` build unlike the earlier direct import of `react-mobiledoc-editor`
2022-07-27 14:14:12 +01:00

47 lines
1.2 KiB
JavaScript

/* global ReactDOM */
import Component from '@glimmer/component';
import {action} from '@ember/object';
export default class ReactComponent extends Component {
@action
renderComponent() {
// eslint-disable-next-line
console.error('Components extending ReactComponent must implement a `renderComponent()` action that calls `this.reactRender()');
}
/**
* Renders a react component as the current ember element
* @param {React.Component} reactComponent. e.g., <HelloWorld />
*/
reactRender(element, reactComponent) {
if (element !== this.elem) {
this.unmountReactElement();
}
this.elem = element;
this.root = ReactDOM.createRoot(this.elem);
this.root.render(reactComponent);
}
/**
* Removes a mounted React component from the DOM and
* cleans up its event handlers and state.
*/
unmountReactElement() {
if (!this.root) {
return;
}
this.root.unmount();
}
/**
* Cleans up the rendered react component as the ember
* component gets destroyed
*/
willDestroy() {
super.willDestroy();
this.unmountReactElement();
}
}