You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository has been archived by the owner on Jan 14, 2020. It is now read-only.
So far so good. Now let's see how the prototype scales to a real world scenario:
Blog needs to asynchronously pull blog config, which includes data that it needs to render and something that child routes will need. For example, { name: 'My Blog', postsPerPage: 10 }
BlogPost needs to know the value of postsPerPage in its getInitialData to construct the API request: await axios.get(..., { ... perPage })
BlogPost needs to tell Blog which post title to render in <h1> (or which category to mark as "current", etc.)
Generalizing, the components in parent/child chain need to push/pull data along the chain. Let's outline the 4 possible scenarios:
Access data coming from parent getInitialData in child getInitialData
Access data coming from child getInitialData in parent getInitialData
Synchronously access data from parent's getInitialData in child template
Synchronously access data from child's getInitialData in parent template
3 is possible with {{ $parent.$parent.xxx }}, not very elegant, but acceptable.
4 is possible with this hack in BlogPost:
exportdefault{asyncgetInitialData({ route }){constpost=awaitaxios.get(...)route.params.title=post.titlereturn{ post }}}
and this in Blog:
exportdefault{beforeCreate(){if(process.server){// Save route params set by a child route in SSR context// this.$initialData will be pushed to this.$data by Reamthis.$initialData.title=this.$route.params.title}else{// Do nothing.// On client, this.$initialData has already been restored from window.__REAM__, and custom $route.params.xxx are NOT set!}}}
which is quite cumbersome.
What I'm thinking (I didn't do much thinking though) is that instead of doing Promise.all, the children getInitialData's could be called sequentially, and include all parents' data in context or as additional parameters. For the blog example, that would be:
This isn't a bug report, but something I wanted to discuss because I am not happy with
getInitialData
in real apps.Let's consider a simple blog/post app, where routes looks like this:
so
/blog
renders the blog index, and/blog/123
renders a post, and they both share the same layout.In a prototype,
Blog
doesn't even needgetInitialData
,BlogIndex
will have something like:and
BlogPost
will have:So far so good. Now let's see how the prototype scales to a real world scenario:
Blog
needs to asynchronously pull blog config, which includes data that it needs to render and something that child routes will need. For example,{ name: 'My Blog', postsPerPage: 10 }
BlogPost
needs to know the value ofpostsPerPage
in itsgetInitialData
to construct the API request:await axios.get(..., { ... perPage })
BlogPost
needs to tellBlog
which post title to render in<h1>
(or which category to mark as "current", etc.)Generalizing, the components in parent/child chain need to push/pull data along the chain. Let's outline the 4 possible scenarios:
getInitialData
in childgetInitialData
getInitialData
in parentgetInitialData
getInitialData
in child templategetInitialData
in parent template1 and 2 are not currently possible as the two
getInitialData
for parent and child run in parallel withPromise.all
:https://github.com/ream/ream/blob/874aa8ef9968b8c77480f3084ef30a99f03e9005/app/server-entry.js#L63 (in theory it can be achieved by using something like a shared promise in
context
, with loopedsetTimeout
to deal with the race condition, but it's unacceptable architecture-wise).3 is possible with
{{ $parent.$parent.xxx }}
, not very elegant, but acceptable.4 is possible with this hack in
BlogPost
:and this in
Blog
:which is quite cumbersome.
What I'm thinking (I didn't do much thinking though) is that instead of doing
Promise.all
, the childrengetInitialData
's could be called sequentially, and include all parents' data in context or as additional parameters. For the blog example, that would be:Blog
:and then - sequentially -
BlogPost
which may both access parent data and push something else to it:This will fix data flow scenarios 1, 4, and possibly simplify 3. Scenario 2 will still not be possible but it is the least natural data flow anyway.
If
BlogPost
had its own child component, that component'sgetInitialData
would be called asgetInitialData(context, blogData, blogPostData)
.The proposed improve will be fully backwards compatible.
Thoughts?
The text was updated successfully, but these errors were encountered: