From e649211597cca5ec40733f82c1a9906ce5e23b56 Mon Sep 17 00:00:00 2001 From: rmorshea Date: Sun, 27 Feb 2022 18:55:50 -0800 Subject: [PATCH] load import source in effect --- docs/source/about/changelog.rst | 13 +++------ .../idom-client-react/src/components.js | 15 +++-------- .../idom-client-react/src/contexts.js | 6 +++++ .../idom-client-react/src/import-source.js | 27 ++++++++++++++++++- .../packages/idom-client-react/src/index.js | 1 + 5 files changed, 41 insertions(+), 21 deletions(-) create mode 100644 src/client/packages/idom-client-react/src/contexts.js diff --git a/docs/source/about/changelog.rst b/docs/source/about/changelog.rst index 6df2b732a..8d1b55346 100644 --- a/docs/source/about/changelog.rst +++ b/docs/source/about/changelog.rst @@ -16,20 +16,15 @@ scheme for the project adheres to `Semantic Versioning `__. Unreleased ---------- -While this release doesn't warrant a minor version bump, the last release should have -been. Thus, to make up for that, this release will be a minor bump. It includes misc -bug fixes, and several feature adds, the most important of which is the addition of the -``use_context`` hook. - Added: - Support for keys in HTML fragments - :issue:`682` +- Use Context Hook - :pull:`585` -**Merged Pull Requests** +Fixed: -- reset schedule_render_later flag after triggering - :pull:`688` -- support keys in HTML fragments - :pull:`683` -- Add Use Context Hook - :pull:`585` +- React warning about set state in unmounted component - :issue:`690` +- Missing reset of schedule_render_later flag - :pull:`688` ---- diff --git a/src/client/packages/idom-client-react/src/components.js b/src/client/packages/idom-client-react/src/components.js index 54a3c1685..c44eed085 100644 --- a/src/client/packages/idom-client-react/src/components.js +++ b/src/client/packages/idom-client-react/src/components.js @@ -3,17 +3,15 @@ import ReactDOM from "react-dom"; import htm from "htm"; import { useJsonPatchCallback } from "./json-patch.js"; -import { loadModelImportSource } from "./import-source.js"; +import { useImportSource } from "./import-source.js"; +import { LayoutContext } from "./contexts.js"; + import { createElementAttributes, createElementChildren, } from "./element-utils.js"; const html = htm.bind(React.createElement); -export const LayoutContext = React.createContext({ - sendEvent: undefined, - loadImportSource: undefined, -}); export function Layout({ saveUpdateHook, sendEvent, loadImportSource }) { const [model, patchModel] = useJsonPatchCallback({}); @@ -101,14 +99,9 @@ function ImportedElement({ model }) { const layoutContext = React.useContext(LayoutContext); const importSourceFallback = model.importSource.fallback; - const [importSource, setImportSource] = React.useState(null); + const importSource = useImportSource(model.importSource); if (!importSource) { - // load the import source in the background - loadModelImportSource(layoutContext, model.importSource).then( - setImportSource - ); - // display a fallback if one was given if (!importSourceFallback) { return html`
`; diff --git a/src/client/packages/idom-client-react/src/contexts.js b/src/client/packages/idom-client-react/src/contexts.js new file mode 100644 index 000000000..c6ad86978 --- /dev/null +++ b/src/client/packages/idom-client-react/src/contexts.js @@ -0,0 +1,6 @@ +import React from "react"; + +export const LayoutContext = React.createContext({ + sendEvent: undefined, + loadImportSource: undefined, +}); diff --git a/src/client/packages/idom-client-react/src/import-source.js b/src/client/packages/idom-client-react/src/import-source.js index de6ebdda6..7c09c7c5d 100644 --- a/src/client/packages/idom-client-react/src/import-source.js +++ b/src/client/packages/idom-client-react/src/import-source.js @@ -1,9 +1,34 @@ +import React from "react"; + +import { LayoutContext } from "./contexts.js"; + import { createElementAttributes, createElementChildren, } from "./element-utils.js"; -export function loadModelImportSource(layoutContext, importSource) { +export function useImportSource(modelImportSource) { + const layoutContext = React.useContext(LayoutContext); + const [importSource, setImportSource] = React.useState(null); + + React.useEffect(() => { + let unmounted = false; + + loadModelImportSource(layoutContext, modelImportSource).then((src) => { + if (!unmounted) { + setImportSource(src); + } + }); + + return () => { + unmounted = true; + }; + }, [layoutContext, modelImportSource, setImportSource]); + + return importSource; +} + +function loadModelImportSource(layoutContext, importSource) { return layoutContext .loadImportSource(importSource.source, importSource.sourceType) .then((module) => { diff --git a/src/client/packages/idom-client-react/src/index.js b/src/client/packages/idom-client-react/src/index.js index bee7de4fd..df461bb84 100644 --- a/src/client/packages/idom-client-react/src/index.js +++ b/src/client/packages/idom-client-react/src/index.js @@ -1,3 +1,4 @@ export * from "./mount.js"; +export * from "./contexts"; export * from "./components.js"; export * from "./server.js";