关于react的forwardRef和memo在ts里的应用

190 阅读1分钟

遇到的问题

今天在基于AgGrid封装一个Table组件时,遇到了一个问题,我们现在编写props时,如果遇到需要传入泛型参数的时候通常是这么写的。

interface ITableProps<T = any>
	extends Omit<
		AgGridReactProps,
		"columnDefs" | "rowData" | "paginationPageSize" | "rowHeight" | "onRowClicked" | "selectionColumnDef"
	> {
	className?: string;
	columns: ColDef<T>[];
	rowData: T[];
	pageSize?: number;
	rowHeight?: number;
	onRowClicked?: (event: RowClickedEvent<T>) => void;
	selectionColumnDef?: SelectionColumnDef;
        // ...其他props
}
const Table = <T,>(props: ITableProps<T>) => {
    return <AgGridReact<T> />
}
export default Table

但是当我需要用,forwardRef以及memo包裹这个组件的时候,就不能这么写了,调用函数无法传入泛型参数

解决办法

查询了很久一直也没找到办法,最后找到了这个网址对forwarRef与ts有详细说明

文中介绍了三种办法:

  1. 使用类型断言的方式
  2. 自定义一个ref放在props上
  3. 重写forwardRef的类型定义

因为一般同时使用forwardRef以及还需要传入泛型参数的组件使用并不是很频繁,并且自定义一个ref类型的prop看上去不够优雅,所以这边选择了第一种方式实现

const CustomTable = <T,>(props: ITableProps<T>, ref: ForwardedRef<AgGridReact<T>>) => {
    return <AgGridReact<T> />
}

type ITableFixedType = <T>(props: ITableProps<T> & { ref?: ForwardedRef<AgGridReact<T>> }) => ReturnType<typeof CustomTable>;

const Table = memo(forwardRef(CustomTable) as ITableFixedType) as ITableFixedType;

export default Table;

这样,使用组件的时候就可以传入泛型参数了!

<Table<LoopRowData> />