最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - React TypeScript & ForwardRef - Property 'ref' does not exist on type 'IntrinsicAtt

programmeradmin0浏览0评论

After dropping quite some time fighting with typings and forwardRefs in React and TypeScript, I am hoping somebody else can clear this up for me.

I am building a DataList ponent which is prised of three pieces:

  • Container to hold all event listeners and logic
  • List itself, a ul
  • List item, an li

Ultimately, the usage would look like this:

<DataList.List ...>
  <DataList.Item ...>content</DataList.Item>
</DataList.List>

To achieve the functionality I need, I am leveraging React.forwardRef, but have found this difficult with TypeScript as I struggle correctly typing the ponents to receive a ref as well as children and additional props.

DataListContainer
I essentially want this ponent to just handle logic and event listeners while returning the primary DataList ponent (shown next). But the key here, is that I need to create the DataList ref here and assign it to the returned ponent.

const DataListContainer: React.FC = ({ children }) => {
  const listRef = useRef<HTMLUListElement>(null);

  return (
      <DataList ref={listRef}>{children}</DataList>
  );
};

DataList
I want the DataList ponent to just handle its UI and props.

interface Props extends TestId {
  focusedItemId?: string;
}

const DataList: React.FC<Props> = React.forwardRef<HTMLUListElement, Props>(
  ({ children, focusedItemId, testId }, ref) => {
    return (
      <ul
        aria-activedescendant={focusedItemId}
        data-test-id={testId}
        ref={ref}
      >
        {children}
      </ul>
    );
  },
);

This isn't quite right, though. As This setup gives me the error

Type '{ children: any[]; ref: RefObject<HTMLUListElement>; }' is not assignable to type 'IntrinsicAttributes & Props & { children?: ReactNode; }'.
  Property 'ref' does not exist on type 'IntrinsicAttributes & Props & { children?: ReactNode; }'.

After dropping quite some time fighting with typings and forwardRefs in React and TypeScript, I am hoping somebody else can clear this up for me.

I am building a DataList ponent which is prised of three pieces:

  • Container to hold all event listeners and logic
  • List itself, a ul
  • List item, an li

Ultimately, the usage would look like this:

<DataList.List ...>
  <DataList.Item ...>content</DataList.Item>
</DataList.List>

To achieve the functionality I need, I am leveraging React.forwardRef, but have found this difficult with TypeScript as I struggle correctly typing the ponents to receive a ref as well as children and additional props.

DataListContainer
I essentially want this ponent to just handle logic and event listeners while returning the primary DataList ponent (shown next). But the key here, is that I need to create the DataList ref here and assign it to the returned ponent.

const DataListContainer: React.FC = ({ children }) => {
  const listRef = useRef<HTMLUListElement>(null);

  return (
      <DataList ref={listRef}>{children}</DataList>
  );
};

DataList
I want the DataList ponent to just handle its UI and props.

interface Props extends TestId {
  focusedItemId?: string;
}

const DataList: React.FC<Props> = React.forwardRef<HTMLUListElement, Props>(
  ({ children, focusedItemId, testId }, ref) => {
    return (
      <ul
        aria-activedescendant={focusedItemId}
        data-test-id={testId}
        ref={ref}
      >
        {children}
      </ul>
    );
  },
);

This isn't quite right, though. As This setup gives me the error

Type '{ children: any[]; ref: RefObject<HTMLUListElement>; }' is not assignable to type 'IntrinsicAttributes & Props & { children?: ReactNode; }'.
  Property 'ref' does not exist on type 'IntrinsicAttributes & Props & { children?: ReactNode; }'.
Share Improve this question asked Mar 6, 2021 at 9:17 DoomageAplenttyDoomageAplentty 2,7328 gold badges33 silver badges48 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 5

You were almost there! Following React TypeScript Cheatsheet the problem is with DataList props. Adding children prop would fix it

interface Props extends TestId {
  children?: ReactNode;
  focusedItemId?: string;
}

I have recreated a simple example in this CodeSandbox

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论