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
