0

I try to not instantiate my styled component in render method, but i need the props of my component to create style, can i do this with a simple function component outside render method ? I have the typescript following error :

No overload matches this call. Overload 1 of 2, '(props: Pick, HTMLElement>, "style" | "title" | "key" | "defaultChecked" | ... 250 more ... | "onTransitionEndCapture"> & { ...; } & { ...; }, "style" | ... 257 more ... | "rowEnd"> & Partial<...>, "style" | ... 257 more ... | "rowEnd"> & { ...; } & { ...; }): ReactElement<...>', gave the following error. Type '{ children: Element[]; className: string; }' is missing the following properties from type 'Pick, HTMLElement>, "style" | "title" | "key" | "defaultChecked" | ... 250 more ... | "onTransitionEndCapture"> & { ...; } & { ...; }, "style" | ... 257 more ... | "rowEnd"> & Partial<...>, "style" | ... 257 more ... | "rowEnd">': photo, rowStart, rowEnd Overload 2 of 2, '(props: StyledComponentPropsWithAs<"figure", any, { photo: Photo; rowStart: number; rowEnd: number; }, never>): ReactElement, string | ... 1 more ... | (new (props: any) => Component<...>)>', gave the following error. Type '{ children: Element[]; className: string; }' is missing the following properties from type 'Pick, HTMLElement>, "style" | "title" | "key" | "defaultChecked" | ... 250 more ... | "onTransitionEndCapture"> & { ...; } & { ...; }, "style" | ... 257 more ... | "rowEnd"> & Partial<...>, "style" | ... 257 more ... | "rowEnd">': photo, rowStart, rowEnd

 type MyProps = {
    className: string,
    photo: IPhoto,
    rowStart: number,
    rowEnd: number,
}

const Figure = styled.figure<{photo: IPhoto, rowStart: number, rowEnd: number}>`
grid-column-start: ${props => props.photo.colStart};
grid-column-end: ${props => props.photo.colEnd};
grid-row-start: ${props => props.rowStart};
grid-row-end: ${props => props.rowEnd};
`; 


const Photo = (props: MyProps) => {
    return (
        <Figure className={props.className}>
            <Link to={`/photo/${props.photo.id}`}>
                <img src={props.photo.url_c} alt={props.photo.title} />
            </Link>
            <figcaption>{props.photo.title}</figcaption>
        </Figure>
    )
}

export default Photo;
Dujard
  • 271
  • 2
  • 7
  • 23
  • 1
    Styled Components do allow you to pass props and can be dynamic based on prop values: https://styled-components.com/docs/basics#adapting-based-on-props – Shawn Yap Mar 13 '20 at 14:46
  • Does this answer your question? [React — Passing props with styled-components](https://stackoverflow.com/questions/52321539/react-passing-props-with-styled-components) – Agney Mar 13 '20 at 21:33
  • It seemed to be the same issue, but i had a typescript error. I edited my question – Dujard Mar 14 '20 at 14:43
  • 1
    @Dujard See [this answer](https://stackoverflow.com/questions/52404958/using-styled-components-with-typescript-prop-does-not-exist/52405602#52405602) – Agney Mar 15 '20 at 03:41
  • @Agney it answer to my question, but i have a typescript error, i can't understand the message, it seems that styled component missing some additional props. I updated my post with error. – Dujard Mar 16 '20 at 09:23

1 Answers1

0

No problem. You can pass props to a styled component.

You just pass props as in a normal component and already inside the styled component you change the styles depending on the props.

You can see an example below.

You have an error. I can explain why it appears. You specify the types for the props that the "Figure" component accepts. You indicate that these props are required! But at the same time, you do not pass them, so an error appears. You indicated that they are required, but did not pass them, hence the error.

Remember, "type: number" is required. "type?: number" is optional, and can be omitted. That is, the difference is in ":" or "?:".

{ rowEnd: number } // is required

{ rowEnd?: number } // is not required

In the example below, I left them required in the "Figure" component. And passed them on. You can change this.

I also destructed the props, which is a bit cleaner than writing "props.something" every time.

type MyProps = {
    className: string;
    photo: IPhoto;
    rowStart: number;
    rowEnd: number;
};

const Figure = styled.figure<{ photo: IPhoto; rowStart: number; rowEnd: number }>`
    grid-column-start: ${p=> p.photo.colStart};
    grid-column-end: ${p => p.photo.colEnd};
    grid-row-start: ${p=> p.rowStart};
    grid-row-end: ${p=> p.rowEnd};
`;

const Photo = ({ photo, rowStart, rowEnd, className }: MyProps) => (
    <Figure className={className} photo={photo} rowStart={rowStart} rowEnd={rowEnd}>
        <Link to={`/photo/${photo.id}`}>
            <img src={photo.url_c} alt={photo.title} />
        </Link>
        <figcaption>{photo.title}</figcaption>
    </Figure>
);

export default Photo;
Ivan Popov
  • 656
  • 2
  • 10