Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PropsTable is not working with components encapsulated by React.forwardRef() #334

Closed
filhocodes opened this issue Sep 14, 2018 · 9 comments
Labels
bug Something isn't working

Comments

@filhocodes
Copy link

<PropsTable of={Input} /> only works when I remove the React.forwardRef(). The following code is Typescript, and I also have typescript: true on my config.

import * as React from "react"
import styled from "styled-components"

// Estilos ---------------------------------------------------------------------

const StyledInput = styled.input.attrs({
  className: "form-control",
})`
  height: 40px;
  margin-bottom: 0;
  font-size: 0.8125rem;
`

const FormRow = styled.div.attrs({
  className: "form-group",
})`
  margin-bottom: 1.25rem;
`

// <Input /> -------------------------------------------------------------------

interface IPInput {
  id: string
  label?: string | false
  placeholder?: string
}

const Input = React.forwardRef(
  (
    { id, label, placeholder, ...extraProps }: IPInput,
    ref: React.RefObject<HTMLInputElement>,
  ) => (
    <FormRow>
      <label
        htmlFor={id}
        className={[false === label ? "sr-only" : ""].join(" ")}
      >
        {false === label && placeholder ? placeholder : label}
      </label>
      <StyledInput
        innerRef={ref}
        id={id}
        placeholder={placeholder}
        {...extraProps}
      />
    </FormRow>
  ),
)

export default Input
@pedronauck pedronauck added the bug Something isn't working label Sep 15, 2018
@sandiiarov
Copy link

sandiiarov commented Nov 4, 2018

I have found a solution but it looks ugly.

// ./MyComponent.js

const WrappedComponent = React.forwardRef(
  function MyComponent(props, ref) {
    return <StyledComponent innerRef={ref} {...props} />;
  }
);

or

// ./MyComponent.js

const MyComponent = (props, ref) => (
  <StyledComponent innerRef={ref} {...props} />;
);

export default React.forwardRef(MyComponent);
// ./MyComponent.mdx

<PropsTable of={WrappedComponent.render} />

@Jared-Dev
Copy link
Contributor

@sandiiarov innerRef has been deprecated in styled-components. forwardRef is what will need to be used in the future.

@sandiiarov
Copy link

@Jared-Dev Yeah I know. It doesn't matter in that example.

@JeroenReumkens
Copy link

It looks like as soon as your component is wrapped inside a HOC, it won't render the prop types. Quickest solution for now is to also export your component as a named export without the HOCs. That way your prop types will work again.

@jnaudin
Copy link

jnaudin commented Jan 25, 2019

Hi

PropsTable uses __docgenInfo's data. you do not have access to it in a HOC but in the wrapped component. You have to give the wrapped component to <PropsTable>

2 solutions :

  • import both component and wrapped component (you have to export wrapped component). Use the wrapped component to display <PropsTable>
// ./MyComponent.js
export const MyComponent = ...;
export default MyHoc(MyComponent);

// ./MyComponent.mdx
import MyComponent, {MyComponent as MyComponentWithPropTypes} from './MyComponent'
<Playground><MyComponent /></Playground>
<PropsTable of={MyComponentWithPropTypes} />
  • use render().type to access to wrapped component via hoc
// ./MyComponent.js
const MyComponent = ...;
export default MyHoc(MyComponent);

// ./MyComponent.mdx
import MyComponent from './MyComponent'
<Playground><MyComponent /></Playground>
<PropsTable of={MyComponent.render().type} />

By default MyComponent.render().type does not have __docgenInfo.
__docgenInfo is generated by babel-plugin-react-docgen and the default value of the resolver option (findAllExportedComponentDefinition) doesn't create the __docgenInfo if the component is not exported. You should use findAllComponentDefinitions value.
See https://github.com/storybooks/babel-plugin-react-docgen#babelrc-options for more info.

Otherwise you should export the wrapped component (like in the first solution) to have access to __docgenInfo.

@zicodeng
Copy link

@jnaudin Thanks for posting such detailed solutions. The first one works great, but the second one I got MyComponent.render is not a function error. Any ideas?

@pedronauck
Copy link
Member

pedronauck commented Mar 12, 2019

I think that this will be fixed in the v1 ✌️

@jnaudin
Copy link

jnaudin commented Mar 12, 2019

@jnaudin Thanks for posting such detailed solutions. The first one works great, but the second one I got MyComponent.render is not a function error. Any ideas?

I think you imported the wrapped component and not the HOC:
import {MyComponent} from './MyComponent'
instead of
import MyComponent from './MyComponent'

Can you show me what your code ?

@pedronauck
Copy link
Member

Closed in favor of the newest release.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

7 participants