Last active
April 8, 2019 10:46
-
-
Save faceyspacey/7142893f50f032bb9c25e025f7e34beb to your computer and use it in GitHub Desktop.
Respond Modular Components
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export default createApp({ | |
components: { | |
App: (props, { location }) => { | |
const Component = location.components.list.ComponentWithHoistedDataDeps | |
return Component ? <Component /> : <Spinner /> | |
}, | |
}, | |
routes: { | |
LIST: { | |
path: '/list/:category', | |
load: async (request, action) => { | |
const module = await import('./component-with-hoisted-data-deps') | |
return module.default({ | |
callbacks: { | |
beforeEnter: 'beforeEnter', | |
thunk: 'thunk', | |
onEnter: 'onEnter' | |
}, | |
deps: { | |
category: action.params.category, // map params to deps!! | |
} | |
}) | |
} | |
} | |
} | |
}) | |
// component-with-hoisted-data-dep.js: | |
export default ({ | |
deps, | |
callbacks: { | |
beforeEnter = 'beforeEnter', | |
thunk = 'thunk', | |
onEnter = 'oneEnter' | |
} | |
}) => createModule({ | |
routes: { | |
entry: { | |
[beforeEnter]: [verifyAccess, saveScroll], | |
[thunk]: ({ api }) => api.get(`items/${deps.category}`), | |
[onEnter]: restoreScroll, | |
} | |
}, | |
components: { | |
ComponentWithHoistedDataDeps: (props, state) => ( | |
<ul> | |
{state.items.map(item => <li>{item.title}</li><)} | |
</ul> | |
) | |
}, | |
reducers: { | |
items: (state, actions) => action.payload | |
} | |
}) |
Lastly, for this to work, the implementation must allow for multiple such components included in a single route, and their callbacks are merged into the array form. For example, we already support:
route.thunk: [callback1, callback2]
They don't currently in parallel. They are sequential (and can be async). So we need to implement a special case where when module components are combined into the same route, they are run in parallel.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
What has to be understood about Respond is that
ComponentWithHoistedDataDeps
will only be available if itsthunk
has run, thereby providing its data. Even if you navigate to another route, and the component is still showing, it will continue to get the same data fromstate
.The
thunk
is guaranteed to have run because its merged into the route that's already executing withload
in the parent module. In other words, because the plane is being built while it's flying we are able to guarantee that both the component and thunk (and reducers) are all available when first rendered.After that, you could perhaps use the component
ComponentWithHoistedDataDeps
on another route, i.e. here:but it will still run because the data it depends on is still stored in its namespaced slot of state.
You could even change its state like this:
You can add additional routes, and event handlers and do all sorts of things. What's important is the initial route using the special name
entry
provides the initial required data.