Skip to content

Commit

Permalink
fix(react): only call createReactManager once
Browse files Browse the repository at this point in the history
Closes #370
  • Loading branch information
ifiokjr committed Jul 25, 2020
1 parent 7d59812 commit 76d1df8
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 13 deletions.
7 changes: 7 additions & 0 deletions .changeset/lazy-shrimps-promise.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@remirror/react': patch
---

- Prevent `createReactManager` being called on every render.
- Accept a `manager` as a parameter for ``createReactManager`
- Improve internal performance of components by caching the `ReactEditorWrapper` after the first render.
12 changes: 11 additions & 1 deletion packages/@remirror/react/src/components/react-editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -576,7 +576,17 @@ type SetShouldRenderClient = Dispatch<SetStateAction<boolean | undefined>>;
function useEditorWrapper<Combined extends AnyCombinedUnion>(
parameter: ReactEditorWrapperParameter<Combined>,
) {
return useRef(new ReactEditorWrapper<Combined>(parameter)).current.update(parameter);
const isFirstMount = useFirstMountState();
const reactEditorWrapper = useRef(
isFirstMount ? new ReactEditorWrapper<Combined>(parameter) : null,
).current?.update(parameter);

invariant(reactEditorWrapper, {
message: 'Problem with `useEditorWrapper` hook.',
code: ErrorConstant.INTERNAL,
});

return reactEditorWrapper;
}

/**
Expand Down
27 changes: 17 additions & 10 deletions packages/@remirror/react/src/hooks/editor-hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
useContext,
useEffect,
useMemo,
useRef,
useState,
} from 'react';

Expand All @@ -21,7 +22,6 @@ import {
invariant,
isFunction,
isPlainObject,
isRemirrorManager,
OptionsOfConstructor,
RemirrorEventListener,
RemirrorManager,
Expand Down Expand Up @@ -384,22 +384,29 @@ type UsePresetCallback<Type extends AnyPresetConstructor> = (
* ```
*/
export function useManager<Combined extends AnyCombinedUnion>(
managerOrCombined: readonly Combined[] | RemirrorManager<ReactCombinedUnion<Combined>>,
combined: readonly Combined[] | RemirrorManager<ReactCombinedUnion<Combined>>,
options: CreateReactManagerOptions = {},
): RemirrorManager<ReactCombinedUnion<Combined>> {
// The manager value for the next update. It is only applied on the first
// render and when the previous manager has been destroyed.
const nextManager = isRemirrorManager<ReactCombinedUnion<Combined>>(managerOrCombined)
? managerOrCombined
: createReactManager(managerOrCombined, options);
const combinedRef = useRef(combined);
const optionsRef = useRef(options);

const [manager, setManager] = useState(nextManager);
// The initial manager which will never be updated.
const initialManager = useMemo(() => {
return createReactManager(combinedRef.current, optionsRef.current);
}, []);

const [manager, setManager] = useState(initialManager);

combinedRef.current = combined;
optionsRef.current = options;

useEffect(() => {
return manager.addHandler('destroy', () => {
setManager(nextManager.clone());
// `clone` is used to ensure that that any stale extensions are
// reinitialized.
setManager(createReactManager(combinedRef.current, optionsRef.current).clone());
});
}, [manager, nextManager]);
}, [manager, initialManager]);

return manager;
}
Expand Down
15 changes: 13 additions & 2 deletions packages/@remirror/react/src/react-helpers.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import { AnyCombinedUnion, BuiltinPreset, RemirrorManager } from '@remirror/core';
import {
AnyCombinedUnion,
BuiltinPreset,
isRemirrorManager,
RemirrorManager,
} from '@remirror/core';
import { CorePreset } from '@remirror/preset-core';
import { ReactPreset } from '@remirror/preset-react';

Expand All @@ -8,11 +13,17 @@ import { CreateReactManagerOptions } from './react-types';
* Create a react manager with all the default react presets and extensions.
*/
export function createReactManager<Combined extends AnyCombinedUnion>(
combined: readonly Combined[],
combined:
| readonly Combined[]
| RemirrorManager<Combined | BuiltinPreset | ReactPreset | CorePreset>,
options: CreateReactManagerOptions = {},
): RemirrorManager<Combined | BuiltinPreset | ReactPreset | CorePreset> {
const { managerSettings: settings, core, react } = options;

if (isRemirrorManager<Combined | BuiltinPreset | ReactPreset | CorePreset>(combined)) {
return combined;
}

return RemirrorManager.create(
[...combined, new ReactPreset(react), new CorePreset(core)],
settings,
Expand Down

0 comments on commit 76d1df8

Please sign in to comment.