Skip to content

Commit

Permalink
Adjust container prop for react 18 (#109)
Browse files Browse the repository at this point in the history
  • Loading branch information
gpoitch authored Aug 8, 2022
1 parent cb34a1f commit b5eb9a4
Show file tree
Hide file tree
Showing 8 changed files with 23 additions and 26 deletions.
7 changes: 3 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -345,15 +345,14 @@ mobiledoc-specific props:

### React 18 Support

To use custom card & atom components in React 18 without warnings, you can pass a specific ReactDOM version as a prop on the Container:
To use custom card & atom components with React 18 without warnings, you can pass an instance of `createRoot` from react-dom v18 as a prop on the `Container`. Internally, components will render with `createRoot` if available and fallback to the legacy `render`:

```js
import ReactDOM from 'react-dom/client';
import { createRoot } from 'react-dom/client';

<Container ReactDOM={ReactDOM}>...</Container>;
<Container createRoot={createRoot}>...</Container>;
```

Notice the React 18 specific import path. Internally, components will render with the new `createRoot` API if available and fallback to the legacy `render` method.

## Development

Expand Down
7 changes: 3 additions & 4 deletions demo/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import ReactDOM from 'react-dom/client';
import { createRoot } from 'react-dom/client';
import '../node_modules/mobiledoc-kit/dist/mobiledoc.css';

import * as ReactMobiledoc from 'react-mobiledoc-editor';
Expand Down Expand Up @@ -46,7 +46,7 @@ const App = () => {
{...config}
mobiledoc={state}
onChange={setState}
ReactDOM={ReactDOM}
createRoot={createRoot}
>
<ReactMobiledoc.Toolbar />
<ImageButton />
Expand All @@ -58,5 +58,4 @@ const App = () => {
);
};

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);
createRoot(document.getElementById('root')).render(<App />);
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "react-mobiledoc-editor",
"version": "0.14.0",
"version": "0.14.1",
"description": "A Mobiledoc editor for React apps",
"repository": "joshfrench/react-mobiledoc-editor",
"homepage": "https://github.com/joshfrench/react-mobiledoc-editor",
Expand Down
6 changes: 3 additions & 3 deletions src/components/Container.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class Container extends React.Component {
placeholder,
serializeVersion,
spellcheck,
ReactDOM,
createRoot,
} = this.props;
const mobiledoc =
this.props.mobiledoc || (html ? undefined : EMPTY_MOBILEDOC);
Expand All @@ -40,7 +40,7 @@ class Container extends React.Component {
...this.props.options,
atoms,
autofocus,
cardOptions: { cardProps, ReactDOM },
cardOptions: { cardProps, createRoot },
cards,
html,
mobiledoc,
Expand Down Expand Up @@ -88,7 +88,7 @@ class Container extends React.Component {
spellcheck,
willCreateEditor,
onChange,
ReactDOM,
createRoot,
...componentProps
} = this.props;
/* eslint-enable no-unused-vars */
Expand Down
6 changes: 3 additions & 3 deletions src/utils/classToAtom.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const atomRenderer =
(component) =>
({ env, options, payload, value }) => {
const { onTeardown } = env;
const { ReactDOM } = options;
const { createRoot } = options;

const element = React.createElement(component, {
...env,
Expand All @@ -15,9 +15,9 @@ const atomRenderer =
});

const targetNode = document.createElement('span');
const root = reactDomRender(ReactDOM, element, targetNode);
const root = reactDomRender(createRoot, element, targetNode);

onTeardown(() => reactDomUnmount(ReactDOM, root, targetNode));
onTeardown(() => reactDomUnmount(root, targetNode));

return targetNode;
};
Expand Down
6 changes: 3 additions & 3 deletions src/utils/classToCard.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const cardRenderer =
({ env, options, payload }) => {
const targetNode = document.createElement('div');
const { didRender, onTeardown } = env;
const { cardProps, ReactDOM } = options;
const { cardProps, createRoot } = options;
let root;

didRender(() => {
Expand All @@ -17,10 +17,10 @@ const cardRenderer =
payload,
isEditing,
});
root = reactDomRender(ReactDOM, element, targetNode);
root = reactDomRender(createRoot, element, targetNode);
});

onTeardown(() => reactDomUnmount(ReactDOM, root, targetNode));
onTeardown(() => reactDomUnmount(root, targetNode));

return targetNode;
};
Expand Down
11 changes: 5 additions & 6 deletions src/utils/react.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
import ReactDOM from 'react-dom';

export function reactDomRender(CustomReactDOM, element, target) {
const ResolvedReactDOM = CustomReactDOM || ReactDOM;
const createRoot = ResolvedReactDOM.createRoot; // React 18+
export function reactDomRender(createRoot, element, target) {
// React 18+
if (createRoot) {
const root = createRoot(target);
root.render(element);
return root;
} else {
ResolvedReactDOM.render(element, target);
ReactDOM.render(element, target);
}
}

export function reactDomUnmount(CustomReactDOM, root, target) {
export function reactDomUnmount(root, target) {
if (root) root.unmount();
else (CustomReactDOM || ReactDOM).unmountComponentAtNode(target);
else ReactDOM.unmountComponentAtNode(target);
}

0 comments on commit b5eb9a4

Please sign in to comment.