Skip to content

Instantly share code, notes, and snippets.

@IrvingArmenta
Created October 2, 2022 02:50
Show Gist options
  • Save IrvingArmenta/a6d7fc76ed538697ad18b7f074accdde to your computer and use it in GitHub Desktop.
Save IrvingArmenta/a6d7fc76ed538697ad18b7f074accdde to your computer and use it in GitHub Desktop.
Example of a forward ref generic component in React 18
import React, { ForwardedRef, forwardRef, MouseEvent } from 'react';
type ClickableListProps<T> = {
items: T[];
onSelect: (
item: T,
event: MouseEvent<HTMLButtonElement, globalThis.MouseEvent>,
) => void;
};
function ClickableListInner<T>(
props: ClickableListProps<T>,
ref: ForwardedRef<HTMLUListElement>,
) {
return (
<ul ref={ref}>
{props.items.map((item, i) => (
<li key={i}>
<>
<button onClick={(e) => props.onSelect(item, e)}>Select</button>
{item}
</>
</li>
))}
</ul>
);
}
const ClickableList = forwardRef(ClickableListInner) as <T>(
props: ClickableListProps<T> & { ref?: ForwardedRef<HTMLUListElement> },
) => ReturnType<typeof ClickableListInner>;
export default ClickableList;
@tungvn
Copy link

tungvn commented May 7, 2024

Thank @IrvingArmenta for contributing to this!

p/s: In case you're a fan of the arrow function (like me), you can use this approach

const ClickableListInner = <T>(
  props: ClickableListProps<T>,
  ref: ForwardedRef<HTMLUListElement>,
) {
  return (
    <ul ref={ref}>
      {props.items.map((item, i) => (
        <li key={i}>
          <>
            <button onClick={(e) => props.onSelect(item, e)}>Select</button>
            {item}
          </>
        </li>
      ))}
    </ul>
  );
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment