Storybook: addon-docs: Props doesn't work when using React.memo.

Created on 21 Jan 2020  路  31Comments  路  Source: storybookjs/storybook

Describe the bug
I trying show the props in docs page using <Props of={Component}/> in .mdx file. But i receive this message "No props found for this component"

To Reproduce
Steps to reproduce the behavior:

  1. Create Component in React and wrapped this with React.memo
  2. Run Storybook and open docs tab
  3. The prop table does not appear

Screenshots
ex1

Code snippets

Button.js

function Button({ label, onClick }) {
  return (
    <ButtonContainer onClick={onClick}>
      <Label> {label} </Label>
    </ButtonContainer>
  );
}

Button.propTypes = {
  label: PropTypes.string.isRequired,
  onClick: PropTypes.func.isRequired,
};

export default React.memo(Button);

button.stories.mdx

# Button

Exemplo do **bot茫o** padr茫o.

<Preview withToolbar>
  <Story name="Default" height="100px" parameters={{ decorators: [withKnobs] }}>
    <Button 
      labelColor={text("Label Color", theme.colors.white)}
      onClick={() => alert("Button Click")} />
  </Story>
</Preview>

## Props

<Props of={Button} />

System:
OS: Linux 4.15 Ubuntu 18.04.3 LTS (Bionic Beaver)
CPU: (4) x64 Intel(R) Core(TM) i5-3570 CPU @ 3.40GHz
Binaries:
Node: 10.15.3 - /usr/local/bin/node
Yarn: 1.19.1 - /usr/bin/yarn
npm: 6.4.1 - /usr/local/bin/npm
Browsers:
Chrome: 78.0.3904.108
Firefox: 72.0.1
npmPackages:
@storybook/addon-actions: 5.3.7 => 5.3.7
@storybook/addon-backgrounds: 5.3.7 => 5.3.7
@storybook/addon-centered: 5.3.7 => 5.3.7
@storybook/addon-docs: 5.3.7 => 5.3.7
@storybook/addon-knobs: 5.3.7 => 5.3.7
@storybook/addon-storysource: 5.3.7 => 5.3.7
@storybook/addon-viewport: 5.3.7 => 5.3.7
@storybook/core: 5.3.7 => 5.3.7
@storybook/react: 5.3.7 => 5.3.7
@storybook/theming: 5.3.7 => 5.3.7
npmGlobalPackages:
@storybook/cli: 5.3.4

P2 docs react props bug has workaround todo

Most helpful comment

FWIW I discovered that <Props of={MemoizedComponent.type} /> will correctly render a props table. No idea what's going on under the hood there, lol

All 31 comments

Unsatisfying workaround is to also export your pure component and use that for documentation purposes

I ran into the same problem and found a solution some time ago: add the proptypes to the memo'ed component and you will be fine. Also I believe this has less to do than storybook than with the way the PropTypes work.

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!

Sorry for the shameless bump, but is this scheduled to be fixed in an upcoming release? :)

@breytex we've consolidated on react-docgen for prop table generation, and according to my repro above it appears to be working fine. Can you try upgrading and let me know if it's working for you?

https://github.com/storybookjs/storybook/blob/next/MIGRATION.md#react-prop-tables-with-typescript

@shilman Is it available in 5.3.x? What should be changed here:

    webpackFinal: async config => {
      config.module.rules.push({
        test: /\.(ts|tsx)$/,
        use: [
          {
            loader: require.resolve('ts-loader'),
            options: {
              configFile: path.resolve(__dirname, './tsconfig.json'),
              transpileOnly: true,
            },
          },
          // Automatics props
          {
            loader: require.resolve('react-docgen-typescript-loader'),
          },
        ],
      });
      config.resolve.extensions.push('.ts', '.tsx');
      return config;
    },
  };

@Vanuan Yeah, it should be available in 5.3.x. You can should be able to add @storybook/[email protected] and get the new config.

Still not working if I use default export.
No props found for this component

What I also noticed is when I use named export, which is currently a working solution rignt now, docs doesn't read the children prop, even if I specifically declare that in my interface.

@mkinfrared are you using babel-plugin-react-docgen or react-docgen-typescript-loader?

@shilman I'm using react-docgen-typescript-loader
I can push my test project to github if it can help you somehow

@mkinfrared it's a known issue in RDTL that's fixed in react-docgen. currently both solutions leave a lot to be desired. See https://github.com/storybookjs/storybook/issues/9556

@mkinfrared if you submit a pr to react-docgen-typescript-loader with just a test case I will try to fix it

FWIW I discovered that <Props of={MemoizedComponent.type} /> will correctly render a props table. No idea what's going on under the hood there, lol

Bump

I am on version 6 now.
If we are using CSF format to write stories for a memoized component
The props table is not getting generated, also the control tab is not getting populated correctly.

const MyComponent = React.memo(function MyComponent({param1, ) {
.....
});

Strangely it seems to work fine for normal function component.

Any workaround for the same.

@SomilKumar what happens when you set:

export default {
  title: '...',
  component: MyComponent.type,
}

@SomilKumar what happens when you set:

export default {
  title: '...',
  component: MyComponent.type,
}

Hi I am using forwardRef in my components and met the same problem, I tried your solution like

export default {
    title: 'Input',
    component: Input.type,
    parameters: {
        docs: { page: docs }
  }, 
}

When I wrote this in my Input.stories, the props is not loaded, I even could not see the box with 'No props found for this component'.

I am on "@storybook/react": "^5.3.19".

@shilman it doesn't render the story altogether. Both for memoized component and normal functional component.

@shilman Open PR to react-docgen-typescript to fix the React.memo behavior

https://github.com/styleguidist/react-docgen-typescript/pull/288

Thanks @hipstersmoothie !

Merged 11 days ago and released in v1.20.4 of react-docgen-typescript. I can confirm my deps went from [email protected] to [email protected]

Unfortunately I still have to unwrap memo from my components or export them separately for documentation as even with your updates there is no documentation from when wrapped in memo

if you get a sample repo up I can take a look

@hipstersmoothie thanks Andrew! (I am also an Andrew!)

Here's the requested repo for you! https://github.com/tm1000/storybook-repro

Look in the stories folder. I commented by providing two examples. One with the direct export (which works) and one with the wrapped export (using memo, does not work)

Thanks!

I am not sure if this is resolved, but I am still facing the same issue, where controls ( props ) are not getting generated automatically if I wrap my components using React.memo
"@storybook/addon-essentials": "^6.0.21",
"@storybook/react": "^6.0.21",
"[email protected]",

@SomilKumar what happens when you set:

export default {
  title: '...',
  component: MyComponent.type,
}

Oh god this solved the same problem I was facing.
Can we please add this as a note in documentation somewhere, I had wasted 2 days just to understand that it is not working because of me using memo. It would have never occurred to me that it was the problem. I had to do hundreds of trial and error to just understand this.

@BhanuSanghi-Dev well... it should be fixed looking at the code changes on [email protected]. So I think the intent of the developers is this is fixed so no note needs to be made. At this point it's more of a bug than anything else. Hopefully the provided repo can help out and it can be solved.

@andezzat this is the issue i was mentioning. i'm thinking maybe your "exotic component logic" from #12638 can fix this problem if applied here:

https://github.com/storybookjs/storybook/blob/next/addons/docs/src/frameworks/react/extractProps.ts#L31-L34

you can see that there's an attempt to do something like it already, but that it's not working as desired.

I was able to resolve this by changing my component from

const myComponent = memo(()=><div>...</div>)
export default myComponent

to

const myComponent = ()=><div>...</div>
export default memo(myComponent)

and then in storybook doing the

export default {
  title: 'myComponent',
  component: myComponent.type,
  decorators: [withKnobs],
};

@lwaghorn

Actually, the exported component is the same in both cases.
It's passing storybook the component as myComponent.type that did the trick!

My PR should make this unnecessary 馃憤

Ol茅!! I just released https://github.com/storybookjs/storybook/releases/tag/v6.1.0-alpha.21 containing PR #12686 that references this issue. Upgrade today to try it out!

You can find this prerelease on the @next NPM tag.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

miljan-aleksic picture miljan-aleksic  路  3Comments

tlrobinson picture tlrobinson  路  3Comments

alexanbj picture alexanbj  路  3Comments

xogeny picture xogeny  路  3Comments

ZigGreen picture ZigGreen  路  3Comments