Weboldal keresés

javascript - React TypeScript & ForwardRef - A 'ref' tulajdonság nem létezik az 'IntrinsicAttributes' típuson


Miután elég sok időt töltöttem azzal, hogy a típusokkal és a forwardRef-ekkel küzdjek a React és TypeScript környezetben, remélem, valaki más tisztázni tudja ezt számomra.

Egy DataList komponenst építek, amely három részből áll:

  • Konténer minden eseményfigyelő és logika tárolására
  • Magának a listának a ul
  • Listaelem, egy li

Végső soron a használat így nézne ki:

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

A szükséges funkcionalitás eléréséhez a React.forwardRef-et használom, de ez nehéznek bizonyult TypeScript-tel, mivel problémát okoz számomra a komponensek helyes típusozása, hogy képesek legyenek ref-et, valamint children-t és további propokat fogadni.

DataListContainer
Lényegében azt szeretném, ha ez a komponens csupán a logikát és az eseményfigyelőket kezelné, miközben visszaadja a fő DataList komponenst (lent látható). De a kulcs itt az, hogy létre kell hoznom a DataList hivatkozást itt, és hozzá kell rendelni a visszaadott komponenshez.

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

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

DataList
Azt szeretném, ha a DataList komponens csak a felhasználói felületét és a props-jait kezelné.

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>
    );
  },
);

Ez azonban nem egészen helyes. Mert ez a beállítás hibát ad.

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; }'.

Válasz #1

Majdnem sikerült! A React TypeScript Cheatsheet szerint a probléma a DataList propjaival van. A children prop hozzáadása megoldaná.

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

Újraalkottam egy egyszerű példát ebben a CodeSandbox-ban

Kapcsolódó cikkek