diff --git a/README.md b/README.md index 870900c..e0a4d24 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ export default () => ( | Prop | Description | Type | Default | | --- | --- | --- | --- | | `items` | List data source. | `T[]` | `[]` | -| `rowKey` | Resolve item identity. | `keyof T \| (item: T) => React.Key` | required | +| `rowKey` | Resolve item identity. | `keyof T \| (item: T, index: number) => React.Key` | required | | `itemRender` | Render each item. | `(item: T, index: number) => React.ReactNode` | required | | `height` | Viewport height. | `number` | - | | `itemHeight` | Estimated item height. | `number` | - | diff --git a/README.zh-CN.md b/README.zh-CN.md index 99316c5..aff075f 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -53,7 +53,7 @@ export default () => ( | 名称 | 说明 | 类型 | 默认值 | | --- | --- | --- | --- | | `items` | 列表数据源。 | `T[]` | `[]` | -| `rowKey` | 解析列表项唯一标识。 | `keyof T \| (item: T) => React.Key` | 必填 | +| `rowKey` | 解析列表项唯一标识。 | `keyof T \| (item: T, index: number) => React.Key` | 必填 | | `itemRender` | 渲染每一项。 | `(item: T, index: number) => React.ReactNode` | 必填 | | `height` | 可视区域高度。 | `number` | - | | `itemHeight` | 预估项高度。 | `number` | - | diff --git a/src/List.tsx b/src/List.tsx index b6bedcb..e9c8591 100644 --- a/src/List.tsx +++ b/src/List.tsx @@ -5,7 +5,7 @@ import VirtualList from './VirtualList'; import type { Group } from './hooks/useGroupSegments'; // ============================== Types =============================== -export type RowKey = keyof T | ((item: T) => React.Key); +export type RowKey = keyof T | ((item: T, index: number) => React.Key); export type ScrollAlign = 'top' | 'bottom' | 'auto'; diff --git a/src/RawList/index.tsx b/src/RawList/index.tsx index d2178d7..f426c66 100644 --- a/src/RawList/index.tsx +++ b/src/RawList/index.tsx @@ -51,7 +51,7 @@ function RawList( // ============================ Render Item =========================== const renderItem = React.useCallback( (item: T, index: number) => { - const key = getItemKey(item); + const key = getItemKey(item, index); const scrollTargetProps = getScrollTargetProps(key, 'item'); return ( diff --git a/src/VirtualList/useFlattenRows.ts b/src/VirtualList/useFlattenRows.ts index 0e4dc7b..dff6067 100644 --- a/src/VirtualList/useFlattenRows.ts +++ b/src/VirtualList/useFlattenRows.ts @@ -23,7 +23,7 @@ export interface FlattenRowsResult { export default function useFlattenRows( data: T[], groupData: Map[]>, - getItemKey: (item: T) => React.Key, + getItemKey: (item: T, index: number) => React.Key, group?: Group, ): FlattenRowsResult { return React.useMemo(() => { @@ -36,7 +36,7 @@ export default function useFlattenRows( type: 'item', item, index, - taggedKey: toTaggedKey(getItemKey(item), 'item'), + taggedKey: toTaggedKey(getItemKey(item, index), 'item'), }); // ============================ No Group ============================== diff --git a/src/hooks/useItemKey.ts b/src/hooks/useItemKey.ts index 07737e5..f3df1d4 100644 --- a/src/hooks/useItemKey.ts +++ b/src/hooks/useItemKey.ts @@ -3,7 +3,9 @@ import { useEvent } from '@rc-component/util'; import type { RowKey } from '../List'; export default function useItemKey(rowKey: RowKey) { - return useEvent((item: T): React.Key => - typeof rowKey === 'function' ? rowKey(item) : (item[rowKey] as React.Key), + return useEvent((item: T, index: number): React.Key => + typeof rowKey === 'function' + ? rowKey(item, index) + : (item[rowKey] as React.Key), ); } diff --git a/tests/listy.test.tsx b/tests/listy.test.tsx index 1c93cdc..fc8c791 100644 --- a/tests/listy.test.tsx +++ b/tests/listy.test.tsx @@ -38,8 +38,8 @@ describe('Listy', () => { expect(screen.getByText('foo')).toBeInTheDocument(); expect(screen.getByText('bar')).toBeInTheDocument(); - expect(rowKey).toHaveBeenCalledWith(items[0]); - expect(rowKey).toHaveBeenCalledWith(items[1]); + expect(rowKey).toHaveBeenCalledWith(items[0], 0); + expect(rowKey).toHaveBeenCalledWith(items[1], 1); }); it('renders group headers with title callback', () => {