Open slowselfip opened 4 years ago
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 30 days. Thanks!
Hi @slowselfip, I think that you are right. Where you able to solve this?
@shilman Have you and the team had the chance to dig deeper into this.
I am experiencing the same issue with react-hook-form
. I isolated the story / stories for easy testing. Embedding a react component with a render prop inside the story is fine when there are no decorators involved.
import React from 'react'
// also exported from '@storybook/react' if you can deal with breaking changes in 6.1
import { Story, Meta } from '@storybook/react/types-6-0'
import {
Controller,
FormProvider,
useForm,
useFormContext
} from 'react-hook-form'
export default {
title: 'Forms/Input',
component: <input />,
argTypes: {},
// This is a workaround for the issue regarding "Maximum call stack size exceeded"
// See https://github.com/storybookjs/storybook/issues/12747
parameters: { docs: { source: { type: 'code' } } }
} as Meta
const reactHookFormProviderDecorator = (Story: Story) => {
const rhFormMethods = useForm()
return (
<FormProvider {...rhFormMethods}>
<form
noValidate
onSubmit={rhFormMethods.handleSubmit((v) => console.log(v))}
>
<Story />
<input type='submit' />
</form>
</FormProvider>
)
}
// This story fails because of the controller and its render method.
const TemplateFailsWithController: Story = (args) => {
const { control } = useFormContext()
return (
<Controller
contro={control}
name='test'
defaultValue='testabc'
render={({ name, value, onChange, ref }) => {
return (
<input
name={name}
value={value}
onChange={onChange}
ref={ref}
{...args}
/>
)
}}
/>
)
}
export const TemplateFailsWithControllerStory = TemplateFailsWithController.bind(
{}
)
TemplateFailsWithControllerStory.decorators = [reactHookFormProviderDecorator]
TemplateFailsWithControllerStory.args = {}
// This story works but with another structure ...
const TemplateWorksWithoutController: Story = (args) => {
const { register } = useFormContext()
return <input name='test' defaultValue='testabc' ref={register} {...args} />
}
export const TemplateWorksWithoutControllerStory = TemplateWorksWithoutController.bind(
{}
)
TemplateWorksWithoutControllerStory.decorators = [
reactHookFormProviderDecorator
]
TemplateWorksWithoutControllerStory.args = {}
const TemplateWorksWithControllerInside: Story = (args) => {
const rhFormMethods = useForm()
return (
<FormProvider {...rhFormMethods}>
<form
noValidate
onSubmit={rhFormMethods.handleSubmit((v) => console.log(v))}
>
<input
name='test'
defaultValue='testabc'
ref={rhFormMethods.register}
{...args}
/>
<input type='submit' />
</form>
</FormProvider>
)
}
export const TemplateWorksWithControllerInsideStory = TemplateWorksWithControllerInside.bind(
{}
)
TemplateWorksWithControllerInsideStory.args = {}
BTW: Thank you very much for this awesome tool ;-)
@gerardo-navarro Instead of <Story/>
try {Story()}
in your decorator?
@gerardo-navarro Instead of
<Story/>
try{Story()}
in your decorator?
@shilman Thank you for your quick response.
Unfortunately, It does not work. The method const { control } = useFormContext()
returns null
which is not suppose to be considering that the FormProvider
was wrapped around it. Given that null
is returned, the following code breaks => TypeError: Cannot read property 'control' of null
Any other ideas?
Hey guys i have the same issue with other decorator:
import { gql } from "@apollo/client";
import { Args } from "@storybook/addons";
import React, { ReactElement } from "react";
import {
FetchStatus,
HeadlessStoryContext,
Loader,
pack,
Prompt,
withHeadless,
} from "storybook-addon-headless";
export default {
title: "Examples/GraphQL",
decorators: [
withHeadless({
graphql: {
uri: "https://alameda-staging.herokuapp.com/graphql",
},
}),
],
parameters: {
headless: {
Artworks: {
query: pack(gql`
{
products {
id
title
enable
slug
variants {
title
outOfStock
}
}
}
`),
autoFetchOnInit: true,
},
},
},
};
export const Artworks = (args: Args, { status, data }) => {
console.log(args, status, data);
return <h1>Hello</h1>;
};
I have the same issue with react-hook-form FormProvider
in the last version of Storybook
import { ReactElement } from "react";
import { FormProvider, useForm } from "react-hook-form";
import { SnackbarProvider } from "notistack";
import { Story } from "@storybook/react";
import { PhotoInput, IPhotoInputProps } from "./index";
export default {
title: "Photo",
component: PhotoInput,
decorators: [
(Story: Story): ReactElement => (
<SnackbarProvider>
<FormProvider {...useForm({ defaultValues: { photo: [] } })}>
<Story />
</FormProvider>
</SnackbarProvider>
),
],
};
const Template: Story<IPhotoInputProps> = args => <PhotoInput {...args} />;
export const Simple = Template.bind({});
Simple.args = {
name: "photo",
};
By the way, SnackbarProvider
is working fine and doesn't throw any error
But for the context of FormProvider - it comes as null
as well as in previous comment
Describe the bug I think that this bug is an effect of a combination between the react-final-form and storybook implementations, possibly it's a problem when the decorator contain a component that uses render prop. It's also possible that this is entirely a problem with react-final-form but I've never seen this issue in any other context that I've used that library. The example below reproduce the error message. By switching the order of the decorators, i.e. having the final-form decorator first and the div-wrapper decorator last, makes it go away.
To Reproduce Init CRA project,
npx create-react-app example --template typescript
cd example
Init storybook
npx sb init
Install final-form and react-final-form
yarn add final-form react-final-form
Add the following story in the stories directory
Expected behavior The decorators should not depend on the order they are defined. Would expect to be able to have the final-form decorator wrapped by the div decorator without getting an exception.
System: System: OS: macOS 10.15.6 CPU: (4) x64 Intel(R) Core(TM) i5-4670 CPU @ 3.40GHz Binaries: Node: 14.8.0 - /usr/local/bin/node Yarn: 1.22.4 - /usr/local/bin/yarn npm: 6.14.7 - /usr/local/bin/npm Browsers: Chrome: 84.0.4147.135 Safari: 13.1.2 npmPackages: @storybook/addon-actions: ^6.0.20 => 6.0.20 @storybook/addon-essentials: ^6.0.20 => 6.0.20 @storybook/addon-links: ^6.0.20 => 6.0.20 @storybook/node-logger: ^6.0.20 => 6.0.20 @storybook/preset-create-react-app: ^3.1.4 => 3.1.4 @storybook/react: ^6.0.20 => 6.0.20