Closed acelaya closed 3 months ago
I created another PR based on this one, where the route matching logic is extracted to its own hook, and the map of route -> module
could be passed as a prop: https://github.com/hypothesis/lms/pull/6357
I just noticed the usage of dynamic import(...)
statements causes rollup to generate individual chunk files for those modules. I guess this should be ok, but I'm checking if it's somehow possible to incorporate them in the same bundle file.
EDIT: the output.inlineDynamicImports
rollup option would solve this if we wish to bundle everything in a single file.
Closing for now, until we come back to this.
This PR introduces a mechanism to load the data needed by a new section just before transitioning to it, allowing to keep the previous section rendered until the loading has finished.
This also provides an alternative approach to handle the initial loading, so it might replace https://github.com/hypothesis/lms/pull/6287
How it works
In order to achieve this, every component which represents a "page" and is therefore linked to a route is now expected to fulfill a module contract, exporting two symbols:
loader
function, which returns a promise resolving the data needed by the component.loaderResult
prop where the result of resolving the loader will be passed.To orchestrate everything, we introduce a new component, which replaces the standard
<Switch />
+<Route />
router components, and uses instances ofuseRoute
to determine the matching route.Once we know the matching route, we use a dynamic
import(...)
to load the corresponding module, call itsloader
, and once resolved, mount the corresponding component.This also allow us to have three states.
loader
has resolved, we replace the rendered component.References
This approach is inspired by how some react full-stack frameworks resolve data loading. In their case data is loaded in the server and then components are hydrated with the result, but conceptually it's similar to this.
loader
function and a React component. The component can get the result of executing the loader function via auseLoaderData()
hook.getServerSideProps
: Page modules export agetServerSideProps
function and a React component. The component gets the result of callinggetServerSideProps
implicitly as props.Considerations and next steps
useRoute
. It somehow matches how the static routing config would work, via<Route />
components, but in the second case the children to render are implicit, while in here we still need to perform extra logic on the combined results of alluseRoute
calls.loader
return an object including the mandatory promise/es to await, and others that should not block rendering children.