Extending HTML elements in React and TypeScript while preserving props

后端 未结 6 1114
星月不相逢
星月不相逢 2021-02-04 23:58

I just can\'t wrap my head around this I guess, I\'ve tried probably half a dozen times and always resort to any... Is there a legitimate way to start with an HTML

相关标签:
6条回答
  • 2021-02-05 00:06

    Seems Like the above answer is outdated.

    In my case I'm wrapping a styled component with a functional component, but still want to expose regular HTML button properties.

    export const Button: React.FC<ButtonProps & React.ButtonHTMLAttributes<HTMLButtonElement>> = ({ children, icon, ...props}) => ( 
      <StyledButton { ...props}>
         { icon && (<i className = "material-icons" >{icon}< /i>)} 
         {children} 
       </StyledButton>);

    0 讨论(0)
  • 2021-02-05 00:06

    I solve this code for me, you just have to import ButtonHTMLAttributes from react and that's it

    import { ButtonHTMLAttributes } from "react";
    
    interface MyButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
        children: any;
    }
    
    export const MyButton = (props: ButtonI) => {
        const { children } = props;
     
        return <button {...props}>{children}</button>;
    };
    
    0 讨论(0)
  • 2021-02-05 00:16

    You can change the definition of your component to allow the react html button props

    class MyButton extends React.Component<MyButtonProps & React.HTMLProps<HTMLButtonElement>, {}> {
        render() {
            return <button {...this.props}/>;
        }
    }
    

    That will tell the typescript compiler that you want to enter the button props along with 'MyButtonProps'

    0 讨论(0)
  • 2021-02-05 00:16

    I encountered the same issue today and here is how I fixed it:

    ReactButtonProps.ts

    import {
      ButtonHTMLAttributes,
      DetailedHTMLProps,
    } from 'react';
    
    /**
     * React HTML "Button" element properties.
     * Meant to be a helper when using custom buttons that should inherit native "<button>" properties.
     *
     * @example type MyButtonProps = {
     *   transparent?: boolean;
     * } & ReactButtonProps;
     */
    export type ReactButtonProps = DetailedHTMLProps<ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>;
    

    Usage in Button-ish component:

    import classnames from 'classnames';
    import React, { ReactNode } from 'react';
    import { ReactButtonProps } from '../../types/react/ReactButtonProps';
    
    type Props = {
      children: ReactNode;
      className?: string;
      mode?: BtnMode;
      transparent?: boolean;
    } & ReactButtonProps;
    
    
    const BtnCTA: React.FunctionComponent<Props> = (props: Props): JSX.Element => {
      const { children, className, mode = 'primary' as BtnMode, transparent, ...rest } = props;
      
      // Custom stuff with props
    
      return (
        <button
          {...rest} // This forward all given props (e.g: onClick)
          className={classnames('btn-cta', className)}
        >
          {children}
        </button>
      );
    };
    
    export default BtnCTA;
    

    Usage:

    <BtnCTA className={'test'} onClick={() => console.log('click')}>
      <FontAwesomeIcon icon="arrow-right" />
      {modChatbot?.homeButtonLabel}
    </BtnCTA>
    

    I can now use onClick because it's allowed due to extending from ReactButtonProps, and it's automatically forwarded to the DOM through the ...rest.

    0 讨论(0)
  • 2021-02-05 00:18

    I always like to do it this way:

    import React from 'react';
    
    interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
      title: string;
      showIcon: boolean;
    }
    
    const Button: React.FC<ButtonProps> = ({ title, showIcon, ...props }) => {
      return (
        <button {...props}>
          {title}
          {showIcon && <Icon/>}
        </button>
      );
    };
    

    Then you can do:

    <Button
      title="Click me"
      onClick={() => {}} {/* You have access to the <button/> props */}
    />
    
    0 讨论(0)
  • 2021-02-05 00:24
      private yourMethod(event: React.MouseEvent<HTMLButtonElement>): void {
      event.currentTarget.disabled = true;
      }  
    
     <Button
     onClick={(event) => this.yourMethod(event)}
     />
    
    0 讨论(0)
提交回复
热议问题