Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.
Sign upCore: Add async loaders #12699
Core: Add async loaders #12699
Conversation
|
Looks great, some comments, mainly documentation |
| const addLoaderDeprecationWarning = deprecate( | ||
| () => {}, | ||
| `\`addLoader\` is deprecated, and will be removed in Storybook 7.0. | ||
| Instead, use \`export const loaders = [];\` in your \`preview.js\`. | ||
| Read more at https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#deprecated-addparameters-and-adddecorator).` | ||
| ); |
tmeasday
Oct 12, 2020
Member
We don't need this we aren't exporting addLoader
We don't need this we aren't exporting addLoader
shilman
Oct 12, 2020
Author
Member
We are exporting it because that's what the virtual module code calls
We are exporting it because that's what the virtual module code calls
| export const decorateStory = (storyFn: StoryFn, decorator: DecoratorFunction) => { | ||
| return (context: StoryContext = defaultContext) => | ||
| decorator( | ||
| // You cannot override the parameters key, it is fixed |
tmeasday
Oct 12, 2020
Member
Can we make an issue (7.0 I guess) to add some more things to this list? Doesn't make sense to be able to override storyId as an example.
Can we make an issue (7.0 I guess) to add some more things to this list? Doesn't make sense to be able to override storyId as an example.
Co-authored-by: Tom Coleman <tom@thesnail.org>
|
How would this work if we need to have an async decorator? Something to this regard:
|
|
@agrohs: you would just refactor things slightly, and add the loader + decorator together: export const loaders = [async () => {
return Promise.resolve({ activeContext: { foo: bar } }),
};
export const decorators = (Story, { loaded: { activeContext } }) => {
return (
<StatefulProvider value={activeContext}>
<Story {...storyContext} />
</StatefulProvider>
)
}Having said that, can you tell us a little bit about your use case? Although this is an escape hatch to support it, we sort of consider async loading of data to be an anti-pattern, so I'm keen to hear about use cases to change my mind on that. |
|
Thanks @tmeasday, that's exactly what I did and seems to be working as expected now...cheers! |
|
one minor detail/question is in trying to prevent the loader from running again if its data has already been loaded (or not changed)? Something similar to the following (though it looks like as of now, we don't have access to loaded in the initial payload of the storyContext sent into the loader??)
|
|
Hmm, I would probably suggest using some external cache here -- I don't know if SB should be doing the caching -- we pass the full context into the loader so for instance the loader could fetch different data depending on the You could do something as simple as using a global var here: let previousContext;
export const loaders = [async ({ loaded: { activeContext: previousContext }}) => {
if (previousContext) {
return previousContext
}
return Promise.resolve({ activeContext: { foo: bar } }).then(v => { previousContext = v; return v });
} |
Issue: #10009
What I did
Asynchronous loaders to provide external data to stories:
unboundStoryFnto story store, deprecatedstoryFnHow to test
See updated stories in
official-storybookandhtml-kitchen-sink