How to properly preload within another saga
MickeyKay opened this issue · 5 comments
Hi there,
I have the following setup, in which everything is server-side-rendered:
- A single higher-order
Article
component which preloads a query for article data. This data includes ids forcommentIds
. - A
Comments
child component, which takes thecommentIds
prop and preloads a query for comment data. - In our SSR data-dependency hook, we run the following:
const preloaders = [
() => preload([Article], renderProps),
];
return runSagas(store, preloaders)
The Article
component is decorated with a getArticleData
saga ala:
@connectWpQuery(getArticleData, shouldUpdate)
Within the getArticleData
saga, we somehow also need to preload our comments data. I've tried doing the following within that saga, but it is not working:
// Fetch article data (works!)
const article = yield doArticleFetch(...);
// Fetch comments data
yield preload(
[Comments],
{ commentIds: getCommentIds(article) },
state
);
. . . and where the Comments
component looks something like this:
function* getCommentsData(props) {
return yield fetchCommentsData(props);
}
@connectWpQuery(getCommentsData, shouldUpdate)
class Comments extends Component {...}
I can see that the fetch is being run and the response looks good if I log from within the top-level getArticleData
saga, however the results are not being added to the store.
Calling runSagas
works well in our primary saga, but manually calling preload
does not appear to be actually populating the store (we've chosen this method because store
is not currently accessible in the saga context - we could update this, however before doing that I'd like to understand if preload
should be working). It's unclear to me whether I'm missing a required piece of the puzzle, however from reading the docs it looks as though we should just be able to call preload
without anything else.
Can you please clarify what's missing, and perhaps provide an E2E example that uses preload
instead of just runSagas
?
Thanks!
Bump ❓
@sdgluck any word here? Apologies for pressing, however this is now something we've got two use cases for so I'll be diving in shortly.
Hey, apologies for the delay in responding.
I have added a test which I think covers what you are asking: https://github.com/outlandishideas/kasia/blob/master/test/util/preload.js#L129
(See this component too, which uses preload
of another Kasai component.)
Take a look and tell me if what you're doing is different and how?
A minimal reproducible example would help if you have the time.
I've noticed that you are not calling the result of your call to preload
.
Like this:
yield preload(
[Comments],
{ commentIds: getCommentIds(article) },
state
)();
//-->^^
preload
returns a generator which needs to be "started" before you yield to it. The reason for this is that usually when you are calling preload
in the context of runSagas
we don't want to actually preload at the time of calling preload
, but defer the execution of preloading to the runSagas
fn where we can pass the current state of the store to each preloader (as per example in docs).
(See this line for an example in the aforementioned tests.)
Looks like the docs are incorrect/misleading on this. Sorry about that.
Aha, worked! Thank you!!!