react-native
react-native copied to clipboard
React Native: Decorators may get applied multiple times
Moved issue: https://github.com/storybook-eol/react-native-storybook/issues/50#issuecomment-320232611
Hi @macrozone Shall we continue discussing the issue here. Thanks
Any idea about this issue? or a proper way how to do react-native-storybook with hot reload properly?
Hi everyone! Seems like there hasn't been much going on in this issue lately. If there are still questions, comments, or bugs, please feel free to continue the discussion. Unfortunately, we don't have time to get to every issue. We are always open to contributions so please send us a pull request if you would like to help. Inactive issues will be closed after 60 days. Thanks!
Hey there, it's me again! I am going close this issue to help our maintainers focus on the current development roadmap instead. If the issue mentioned is still a concern, please open a new ticket and mention this old one. Cheers and thanks for using Storybook!
Am facing this issue when using global decorators for React Native storybook. Seems to be okay when I add a decorator to each story individually though, only gets affected by hot reload when it's a global decorator. On version 5.3.25.
@sammiepls Thanks for reporting this, I'll keep it in mind. Likely a fix will be part of the 6.0 release I'll make sure to test this once I have an alpha ready.
I'm bumping into this issue when I attempt to decorate stories with the auth providers necessary to work with firebase/reactfire, regardless of hot reload status.
I'm bumping into this issue when I attempt to decorate stories with the auth providers necessary to work with firebase/reactfire, regardless of hot reload status.
@luciddr34m3r What version of storybook are you using? If you can provide a repo with a minimal reproduction that would be awesome for helping debug the issue.
Here's all my storybook deps:
"@storybook/addon-actions": "^6.3.8",
"@storybook/addon-essentials": "^6.3.8",
"@storybook/addon-links": "^6.3.8",
"@storybook/node-logger": "^6.3.8",
"@storybook/preset-create-react-app": "^3.2.0",
"@storybook/react": "^6.3.8"
Unfortunately the project is in a private repo but I can provide some snippets.
The decorator looks like this:
// preview.js
export const decorators = [
(Story) => (
<ThemeProvider theme={mainTheme}>
<Story />
</ThemeProvider>
),
(Story) => (
<SnackbarProvider maxSnack={3}>
<Story />
</SnackbarProvider>
),
(Story) => (
<FirebaseAppProvider firebaseConfig={firebaseConfig}>
<Story />
</FirebaseAppProvider>
),
];
The FirebaseAppProvider initializes a connection to firebase, but if the project has already been initialized, it will throw an error, so if I flip between stories, it seems to wrap the new story in a new decorator which re-initializes the database connection and pitches an error.
Pretty much the best I can do for now but I think the code will be public in awhile.
@luciddr34m3r this is the react-native repo, you might need to post an issue on the main repo https://github.com/storybookjs/storybook/issues
Derp. Seemed nearly identical to the linked thread.
Thanks.
Derp. Seemed nearly identical to the linked thread.
Thanks.
@luciddr34m3r no problem it's an easy mistake to make :)
Still happening on @storybook/react-native: 5.3.25
Apparently this only happens when all these happen at the same time:
- You have global decorators
- You have fast refreshes triggered by editing a story file
Example decorators where this issue can be seen:
addDecorator((getStory, context) => {
return <View style={{ padding: 20, flex: 1 }}>{getStory(context)}</View>;
})
addDecorator(withBackgrounds) // @storybook/addon-ondevice-backgrounds
SOLUTION
Here's what I have done to fix the issue on my project:
Create these functions (I'm using Typescript here):
import { isValidElement, ReactElement, Fragment } from 'react';
import { DecoratorFunction } from '@storybook/addons';
import { addDecorator } from '@storybook/react-native';
const isReactElement = (value: unknown): value is ReactElement => {
if (typeof value !== 'object') return false;
return isValidElement(value);
};
const WRAPPER_ID = '__fast-refresh-fix';
const preventRedecorationAfterFastRefresh = (
decorator: DecoratorFunction<unknown>,
): DecoratorFunction<unknown> => {
return (getStory, context) => {
const story = getStory(context);
// check if the story has already run through the decorators before the fast refresh
// if yes, don't decorate the story and return the old story element
if (isReactElement(story) && story.key === WRAPPER_ID) return story;
return decorator(getStory, context);
};
};
preventRedecorationAfterFastRefresh.decorator = ((getStory, context) => {
const story = getStory(context);
if (!isReactElement(story)) return story;
// This acts as a flag to tell us whether the story has already run through the decorators
return (
<Fragment key={WRAPPER_ID} >
{story}
</Fragment>
);
}) as DecoratorFunction<unknown>;
Apply them like below
// Note that these are GLOBAL decorators
addDecorator(preventRedecorationAfterFastRefresh(decoratorA));
addDecorator(preventRedecorationAfterFastRefresh(decoratorB));
addDecorator(preventRedecorationAfterFastRefresh(decoratorC));
// this has to be the last call in the chain
addDecorator(preventRedecorationAfterFastRefresh.decorator);
It seems it was added in v60 of react native storybook
in the latest v6 beta you can add this to Storybook.tsx at the top of the file as a workaround. You get a warning though.
import { clearDecorators } from "@storybook/react-native";
clearDecorators();
I'm looking for a better solution still.
Added a workaround in the storybook.requires file generation so I think this is at least partially solved.
@dannyhw Should clearDecorators() be removed to be used with Storybook 7.* versions?
@maharjanrajans v6 isn't compatible with v7 so im not sure what the question refers to
@dannyhw yeah, I mean are we planning to upgrade project to V7 to get rid of this warning.
WARN
clearDecorators is deprecated and will be removed in Storybook 7.0.
As, this doesn't do trick to hide the logs
if (__DEV__) {
// stops the warning from showing on every HMR
require("react-native").LogBox.ignoreLogs([
"`clearDecorators` is deprecated and will be removed in Storybook 7.0",
]);
}
V7 is planned but that will require changes to the integration with storybook core apis and v6 is still stabilising.
Since the warning comes from storybook core apis so it can't be removed easily before v7.
Also you can ignore the warning since it doesn't effect anything.
Hello 👋 Is the team still planning to migrate to V7?
@hayata-suenaga yes there are already prs in progress for this
Hi @dannyhw,
Do you know by any chance why LogBox is not muting a warning about decorators?
"react-native": "0.72.5",
logbox doesn't remove logs from metro just stops the logbox ui from showing on the device
should be resolved in latest versions