reactjs - Stilkomponent i HOC


Jeg vil legge til stiler til komponentinnpakningen min ved å bruke en høyere ordens komponent. Typescript sier at det er en feil med ComponentWithAdddedColors.

type Props = {
  bg?: string;
};

function withColors<TProps>(
  Component: React.ComponentType<TProps>
): React.ComponentType<TProps & Props> {

  const ColoredComponent: React.ComponentType<TProps & Props> = props => {
    const { bg, ...componentProps } = props;

    const ComponentWithAdddedColors = styled(Component)`
      ${bg && `background: ${bg};`}
    `;

    return <ComponentWithAdddedColors {...componentProps} />; //Typecheck error
  };

  return ColoredComponent;
}

Når jeg vil returnere en komponent som ble sendt til HOC med {...componentProps}, er det også en typekontrollfeil.

...
{
  const ColoredComponent: React.ComponentType<TProps & Props> = props => {
    const { bg, ...componentProps } = props;

    return <Component {...componentProps} />; //Typecheck error
  };

  return ColoredComponent;
}

Men når jeg sender alt til Component med {...props}, er det ingen typekontrollfeil.

...
{
  const ColoredComponent: React.ComponentType<TProps & Props> = props => {
    return <Component {...props} />; //No error
  };

  return ColoredComponent;
}

Svar #1

Er dette det du prøver å gjøre?

export function withColors<T>(Component: React.ComponentType<T>) {
    return styled(Component)<Props>`
        ${({ bg }) => bg && `background: ${bg};`}
    `
}

const Foo: React.FC<{ bar: string }> = props => <div>{props.bar}</div>
const ColoredFoo = withColors(Foo)
export const redFoo = <ColoredFoo bg="red" bar="baz" />

Hvis du derimot ønsket å låse fargene dine og ikke eksponere farge-egenskapene, er jeg redd du kan ha avdekket en TypeScript-feil. Jeg ser ikke ut til å komme rundt det selv (uten å bruke additionalProps as any); likevel tilnærmet jeg det på en litt annerledes måte.

function withColors<T>(Component: React.ComponentType<T>, additionalProps: Props) {
    const { bg } = additionalProps;
    const ComponentWithAddedColors = styled(Component)<Props>`
        ${bg && `background: ${bg};`}
    `
    const result: React.FC<T> = props => (
        <ComponentWithAddedColors {...props} {...(additionalProps as any)} />
    )
    return result
}

export const RedFoo = withColors(Foo, { bg: 'red' })