hoc react组件中的样式化组件

金·弗罗斯特·尼尔森

我在使用hoc包装器中的样式化组件时有两个问题。

  1. 组件被渲染,但是没有背景色。
  2. ComponentWithAddedColors无效的打字稿。不知道为什么。

有人可以帮忙吗?

interface IProps {
  id: string;
  left: number;
  top: number;
}

export const Node: React.FC<IProps> = ({ id, left, top }) => {
  return (
    <Container left={left} top={top}>
      {id}
    </Container>
  );
};

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

const DraggableNode = withColors(Node);
export default DraggableNode;

我已经制作了一个代码沙箱来说明问题:https : //codesandbox.io/s/styled-hoc-xgduo?file=/ src/Components/Node/ Node.tsx

可爱的女皇

解释样式错误

@Mosh Feu的评论向我指出了正确的方向。

您可以将样式添加到已样式化的组件中,也可以将样式添加到自定义组件中,但是这两件事的工作方式有所不同。您有一条贯穿这两种类型的链条,因此事情正在迷失。

当您打电话时withColors(Node),这是在将生成的classNameprop传递Node但是您的自定义组件Node无法使用此道具做任何事情,因此该样式永远不会应用。

样式化的方法只要将传递的className属性附加到DOM元素上,便可以在您自己或任何第三方组件上完美运行。

修正样式错误

如果我们编辑Node使用此className颜色,我们将获得颜色!

export const Node: React.FC<IProps & {className?: string}> = ({ id, left, top, className}) => {
  return (
    <Container left={left} top={top} className={className}>
      {id}
    </Container>
  );
};

TS错误说明

就打字稿错误而言,您在将自己的道具分配给T样式化组件(ComponentWithAddedColors的道具时遇到了一个错误,它显示为一堆疯狂的废话:

(props:(Pick <Pick <(PropsWithoutRef&RefAttributes <Component <T,any,any >>)|(PropsWithRef <PropsWithChildren>&{}),排除<...> | ... 1更多... |排除<... >>和Partial <...>,排除<...> | ... 1个其他... |排除<... >>和{...;}&{... ;})|(Pick <...>&... 2更多...&{...;})):ReactElement <...>

这主要是因为ref通过该ForwardRefExoticComponent类型转发

但是我们可以使用实用程序类型进行反向工作,以从组件类型中获得预期的道具类型:

type PropsOf<T> = T extends React.ComponentType<infer P> ? P : never;

因此,ComponentWithAddedColors有道具PropsOf<typeof ComponentWithAddedColors>我们可以使用它,但是我们也知道它ComponentWithAddedColors具有type StyledComponent<React.ComponentType<T>, any, {}, never>,所以我们可以再往回走一步:

type StyledProps<InitialProps> = PropsOf<StyledComponent<React.ComponentType<InitialProps>, any, {}, never>>

因此,ComponentWithAddedColors有道具StyledProps<T>

TS错误已修复

也就是说,所有这些都是不必要的,至少在您显示的示例中。您将把所有的道具ComponentWithAddedColors传递给ComponentWithAddedColors,所以result与组件本身一样。只需直接将其退回即可。

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

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章