代码之家  ›  专栏  ›  技术社区  ›  Kernel James

带有“as”属性的React组件,该属性指向另一个组件并继承其属性

  •  1
  • Kernel James  · 技术社区  · 2 年前

    我想用“ as “允许其继承的财产 作为 组件,这样我就可以得到TypeScript类型。

    例如

    HTML元素用法:

    <MyComponent 
      as="label" 
      htmlFor="caption" /* this should autocomplete from label */
      asdf="" /* this should give error */
      className="test"
    >
      Test
    </MyComponent>
    

    使用React组件:

    <MyComponent 
      as={MyGrid} 
      rows={4}  /* this should autocomplete from MyGrid */ 
      asdf="" /* this should give error */
    
    >
      Test
    </MyComponent>
    

    到目前为止,我已经有了这个组件,但不幸的是,它没有继承类型。

    import { useRef, forwardRef } from "react";
    import type {
      PropsWithChildren,
      ElementType,
      ComponentProps,
      ForwardedRef,
      ReactElement,
    } from "react";
    
    
    type MyProps<T extends ElementType> = 
      ComponentProps<T> &
      PropsWithChildren & 
      { as?: T };
    
    function _MyComponent<T extends ElementType = "div">(
      { as, children, ...props }: MyProps<T>,
      ref: ForwardedRef<HTMLElement>,
    ): ReactElement<T> {
      
      const Comp = as ?? "div";
    
      return (
        <Comp {...props} ref={ref}>
          {children}
        </Comp>
      );
    }
    
    const MyComponent = forwardRef(_MyComponent);
    export default MyComponent;
    

    我需要如何更改字体才能获得字体建议?

    1 回复  |  直到 2 年前
        1
  •  1
  •   docker compose    2 年前

    我通过在forwardRef调用中添加类型断言来实现它:

    export const MyComponent = forwardRef(_MyComponent) as <
      T extends ElementType = "div"
    >(
      props: MyProps<T> & { ref?: React.Ref<Element> }
    ) => ReactElement | null;
    

    使用方法

    <MyComponent 
      as="label" 
      htmlFor="caption" // this autocompletes 
      asdf="" // this gives error
    >
      Test
    </MyComponent>
    
    const MyGrid = ({ rows }: { rows: number }) => (
      <div style={{ gridTemplateRows: `repeat(${rows}, 1fr)` }}></div>
    );
    
    <MyComponent as={MyGrid} rows={4}>Test</MyComponent>;
    

    编辑

    修改 MyProps 所以它适用于HTML元素

    type MyProps<T extends ElementType> = {
      as?: T;
    } & ComponentPropsWithoutRef<T>;
    
    推荐文章