react-redux-typescript-guide icon indicating copy to clipboard operation
react-redux-typescript-guide copied to clipboard

How to use forwardRef?

Open albertorestifo opened this issue 6 years ago • 12 comments

What is the correct way to type a component which uses forwardRef form React 16.3?

albertorestifo avatar May 03 '18 10:05 albertorestifo

You can try to use this way:

export type ComponentProps = {
    foo?: boolean;
    bar: string;
    className?: string;
};


export const Component = React.forwardRef(
    (props: ComponentProps, ref?: React.Ref<HTMLButtonElement>) => {
        const { className, foo, bar } = props;

        return (
            <button className={className} ref={ref}>
                {foo ? bar : 'Buz'}
            </button>
        );
    },
);

IOuser avatar Aug 22 '18 15:08 IOuser

@boostio funded this issue with $20. Visit this issue on Issuehunt

IssueHuntBot avatar Sep 15 '18 04:09 IssueHuntBot

@boostio funded this issue with $20. Visit this issue on Issuehunt

IssueHuntBot avatar Sep 15 '18 04:09 IssueHuntBot

@boostio cancelled funding, $20, of this issue. Visit this issue on Issuehunt

IssueHuntBot avatar Sep 15 '18 04:09 IssueHuntBot

@issuehuntfest has funded $20.00 to this issue. See it on IssueHunt

IssueHuntBot avatar Dec 03 '18 09:12 IssueHuntBot

@adrienharnay has submitted a pull request. See it on IssueHunt

IssueHuntBot avatar Dec 11 '18 09:12 IssueHuntBot

export const Component = React.forwardRef<HTMLButtonElement, ComponentProps>(
  (props, ref) => {
    return (
      <button {...props} ref={ref}>
         Submit
      </button>
    );
  }
);

kyle-villeneuve avatar Dec 18 '19 05:12 kyle-villeneuve

So @kyle-villeneuve do you have to deconstruct props to make it work? Can't do this?

export const Component = React.forwardRef<HTMLButtonElement, ComponentProps>(
  (props, ref) => {
    return (
      <button ref={ref} {...props}>Stuff</button>
    );
  }
);

martisj avatar Mar 05 '20 09:03 martisj

So @kyle-villeneuve do you have to deconstruct props to make it work? Can't do this?

export const Component = React.forwardRef<HTMLButtonElement, ComponentProps>(
  (props, ref) => {
    return (
      <button ref={ref} {...props}>Stuff</button>
    );
  }
);

Yes @martisj, just make sure your ComponentProps interface extends React.HTMLProps<HTMLButtonElement>

sebastiandg7 avatar Mar 21 '20 13:03 sebastiandg7

@IOuser great! thank u

thainabiudes avatar Jul 30 '20 15:07 thainabiudes

export const Component = React.forwardRef<HTMLButtonElement, ComponentProps>(
  (props, ref) => {
    return (
      <button {...props} ref={ref}>
         Submit
      </button>
    );
  }
);

Brooo <3 <3 <3

DedaDev avatar Aug 28 '20 19:08 DedaDev

I'm proposing this updated version instead, which adds usage example and has a more dev friendly displayName in the DevTools:

export interface FancyButtonProps {
  className?: string;
  children?: React.ReactNode;
}

// using function DevTools will show "ForwardRef(FancyButton)" instead of just "ForwardRef"
export const FancyButton = React.forwardRef<HTMLButtonElement, FancyButtonProps>(
  function FancyButton(props, ref) {
    return (
      <button ref={ref} className="FancyButton" {...props} >
         {props.children}
      </button>
    );
  }
);

const ref = React.createRef<HTMLButtonElement>();
<FancyButton ref={ref}>Click me!</FancyButton>;

piotrwitek avatar Apr 14 '22 12:04 piotrwitek