Skip to content

update to @rc-component/virtual-list #310

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ lib/
~*
yarn.lock
package-lock.json
pnpm-lock.yaml
!tests/__mocks__/rc-util/lib
bun.lockb

Expand Down
25 changes: 10 additions & 15 deletions examples/animate.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
/* eslint-disable arrow-body-style */

import * as React from 'react';
// @ts-ignore
import CSSMotion from 'rc-animate/lib/CSSMotion';
import CSSMotion from '@rc-component/motion';
import type { CSSMotionRef } from '@rc-component/motion/lib/CSSMotion';
import classNames from 'classnames';
import List, { ListRef } from '../src/List';
import useLayoutEffect from 'rc-util/lib/hooks/useLayoutEffect';
import useLayoutEffect from '@rc-component/util/lib/hooks/useLayoutEffect';
import './animate.less';

let uuid = 0;
Expand Down Expand Up @@ -44,7 +42,7 @@ const getMaxHeight = (node: HTMLElement) => {
};
const getCollapsedHeight = () => ({ height: 0, opacity: 0 });

const MyItem: React.ForwardRefRenderFunction<any, MyItemProps> = (
const MyItem: React.ForwardRefRenderFunction<CSSMotionRef, MyItemProps> = (
{
id,
uuid: itemUuid,
Expand Down Expand Up @@ -74,7 +72,7 @@ const MyItem: React.ForwardRefRenderFunction<any, MyItemProps> = (
motionName="motion"
motionAppear={motionAppear}
onAppearStart={getCollapsedHeight}
onAppearActive={node => {
onAppearActive={(node) => {
motionRef.current = true;
return getMaxHeight(node);
}}
Expand Down Expand Up @@ -135,7 +133,7 @@ const Demo = () => {
const [animating, setAnimating] = React.useState(false);
const [insertIndex, setInsertIndex] = React.useState<number>();

const listRef = React.useRef<ListRef>();
const listRef = React.useRef<ListRef>(null);

const onClose = (id: string) => {
setCloseMap({
Expand All @@ -145,7 +143,7 @@ const Demo = () => {
};

const onLeave = (id: string) => {
const newData = data.filter(item => item.id !== id);
const newData = data.filter((item) => item.id !== id);
setData(newData);
};

Expand All @@ -159,14 +157,14 @@ const Demo = () => {
}

const onInsertBefore = (id: string) => {
const index = data.findIndex(item => item.id === id);
const index = data.findIndex((item) => item.id === id);
const newData = [...data.slice(0, index), genItem(), ...data.slice(index)];
setInsertIndex(index);
setData(newData);
lockForAnimation();
};
const onInsertAfter = (id: string) => {
const index = data.findIndex(item => item.id === id) + 1;
const index = data.findIndex((item) => item.id === id) + 1;
const newData = [...data.slice(0, index), genItem(), ...data.slice(index)];
setInsertIndex(index);
setData(newData);
Expand All @@ -187,10 +185,7 @@ const Demo = () => {
itemKey="id"
// disabled={animating}
ref={listRef}
style={{
border: '1px solid red',
boxSizing: 'border-box',
}}
style={{ border: '1px solid red', boxSizing: 'border-box' }}
// onSkipRender={onAppear}
// onItemRemove={onAppear}
>
Expand Down
2 changes: 1 addition & 1 deletion examples/basic.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ interface Item {
id: number;
}

const MyItem: React.ForwardRefRenderFunction<any, Item> = ({ id }, ref) => (
const MyItem: React.ForwardRefRenderFunction<HTMLSpanElement, Item> = ({ id }, ref) => (
<span
ref={ref}
style={{
Expand Down
4 changes: 2 additions & 2 deletions examples/height.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ interface Item {
height: number;
}

const MyItem: React.ForwardRefRenderFunction<HTMLElement, Item> = ({ id, height }, ref) => {
const MyItem: React.ForwardRefRenderFunction<HTMLSpanElement, Item> = ({ id, height }, ref) => {
return (
<span
ref={ref}
Expand Down Expand Up @@ -50,7 +50,7 @@ const Demo = () => {
boxSizing: 'border-box',
}}
>
{item => <ForwardMyItem {...item} />}
{(item) => <ForwardMyItem {...item} />}
</List>
</div>
</React.StrictMode>
Expand Down
2 changes: 1 addition & 1 deletion examples/nest.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ for (let i = 0; i < 100; i += 1) {
});
}

const MyItem: React.ForwardRefRenderFunction<any, Item> = ({ id }, ref) => (
const MyItem: React.ForwardRefRenderFunction<HTMLDivElement, Item> = ({ id }, ref) => (
<div style={{ padding: 20, background: 'yellow' }} ref={ref}>
<List
data={data}
Expand Down
10 changes: 5 additions & 5 deletions examples/no-virtual.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ interface Item {
height: number;
}

const MyItem: React.FC<Item> = ({ id, height }, ref) => {
const MyItem: React.ForwardRefRenderFunction<HTMLSpanElement, Item> = ({ id, height }, ref) => {
return (
<span
ref={ref}
Expand Down Expand Up @@ -50,7 +50,7 @@ const Demo = () => {
boxSizing: 'border-box',
}}
>
{item => <ForwardMyItem {...(item as any)} />}
{(item) => <ForwardMyItem {...(item as any)} />}
</List>

<h2>Less Count</h2>
Expand All @@ -64,7 +64,7 @@ const Demo = () => {
boxSizing: 'border-box',
}}
>
{item => <ForwardMyItem {...(item as any)} />}
{(item) => <ForwardMyItem {...(item as any)} />}
</List>

<h2>Less Item Height</h2>
Expand All @@ -78,7 +78,7 @@ const Demo = () => {
boxSizing: 'border-box',
}}
>
{item => <ForwardMyItem {...(item as any)} />}
{(item) => <ForwardMyItem {...(item as any)} />}
</List>

<h2>Without Height</h2>
Expand All @@ -91,7 +91,7 @@ const Demo = () => {
boxSizing: 'border-box',
}}
>
{item => <ForwardMyItem {...(item as any)} />}
{(item) => <ForwardMyItem {...(item as any)} />}
</List>
</div>
</React.StrictMode>
Expand Down
13 changes: 5 additions & 8 deletions examples/switch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ interface Item {
id: number;
}

const MyItem: React.FC<Item> = ({ id }, ref) => (
const MyItem: React.ForwardRefRenderFunction<HTMLSpanElement, Item> = ({ id }, ref) => (
<span
ref={ref}
style={{
Expand All @@ -23,7 +23,7 @@ const MyItem: React.FC<Item> = ({ id }, ref) => (
</span>
);

const ForwardMyItem = React.forwardRef(MyItem as any);
const ForwardMyItem = React.forwardRef<HTMLSpanElement, Item>(MyItem);

function getData(count: number) {
const data: Item[] = [];
Expand All @@ -39,7 +39,7 @@ const Demo = () => {
const [height, setHeight] = React.useState(200);
const [data, setData] = React.useState(getData(20));
const [fullHeight, setFullHeight] = React.useState(true);
const listRef = React.useRef<ListRef>();
const listRef = React.useRef<ListRef>(null);

return (
<React.StrictMode>
Expand Down Expand Up @@ -117,12 +117,9 @@ const Demo = () => {
itemHeight={10}
itemKey="id"
fullHeight={fullHeight}
style={{
border: '1px solid red',
boxSizing: 'border-box',
}}
style={{ border: '1px solid red', boxSizing: 'border-box' }}
>
{(item, _, props) => <ForwardMyItem {...(item as any)} {...props} />}
{(item, _, props) => <ForwardMyItem {...item} {...props} />}
</List>
</div>
</React.StrictMode>
Expand Down
31 changes: 16 additions & 15 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "rc-virtual-list",
"version": "3.18.6",
"name": "@rc-component/virtual-list",
"version": "1.0.0",
"description": "React Virtual List Component",
"engines": {
"node": ">=8.x"
Expand Down Expand Up @@ -36,19 +36,23 @@
"test": "rc-test",
"now-build": "npm run build"
},
"peerDependencies": {
"react": ">=16.9.0",
"react-dom": ">=16.9.0"
"dependencies": {
"@babel/runtime": "^7.20.0",
"@rc-component/resize-observer": "^1.0.0",
"@rc-component/util": "^1.2.1",
"classnames": "^2.2.6"
},
"devDependencies": {
"@rc-component/father-plugin": "^1.0.2",
"@rc-component/motion": "^1.1.4",
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^12.1.5",
"@types/classnames": "^2.2.10",
"@types/enzyme": "^3.10.5",
"@types/jest": "^25.1.3",
"@types/react": "^18.0.8",
"@types/react-dom": "^18.0.3",
"@types/node": "^22.15.18",
"@types/react": "^19.1.4",
"@types/react-dom": "^19.1.5",
"@types/warning": "^3.0.0",
"cheerio": "1.0.0-rc.12",
"cross-env": "^5.2.0",
Expand All @@ -61,16 +65,13 @@
"father": "^4.4.0",
"glob": "^7.1.6",
"np": "^5.0.3",
"rc-animate": "^2.9.1",
"rc-test": "^7.0.15",
"react": "16.14.0",
"react-dom": "16.14.0",
"react": "^19.1.0",
"react-dom": "^19.1.0",
"typescript": "^5.0.0"
},
"dependencies": {
"@babel/runtime": "^7.20.0",
"classnames": "^2.2.6",
"rc-resize-observer": "^1.0.0",
"rc-util": "^5.36.0"
"peerDependencies": {
"react": ">=18.0.0",
"react-dom": ">=18.0.0"
}
Comment on lines +73 to 76
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

❓ Verification inconclusive

对等依赖要求提高

将 React 和 ReactDOM 的最低版本要求从 >=16.9.0 提高到 >=18.0.0,这是一个破坏性变更。不再支持 React 16 和 17。

请确保:

  1. 在发布说明中明确标记这是一个破坏性变更
  2. 提供升级指南给仍在使用旧版本 React 的用户

🏁 Script executed:

#!/bin/bash
# 检查项目中是否有任何依赖于 React 16 或 17 特定功能的代码
rg "React\.version|react-dom.*16|react-dom.*17|\bReact\.render\b|\bfindDOMNode\b|\bunmountComponentAtNode\b" --type ts --type tsx

Length of output: 159


以下脚本将修正文件类型过滤,重新在 .ts.tsx 文件中搜索 React 16/17 特定 API:


🏁 Script executed:

#!/bin/bash
# 在 .ts 和 .tsx 文件中检查是否使用了 React 16/17 特定 API
rg "React\.version|react-dom.*16|react-dom.*17|\bReact\.render\b|\bfindDOMNode\b|\bunmountComponentAtNode\b" -g '*.ts' -g '*.tsx'

Length of output: 131


下面再在 .js.jsx 文件中执行相同的检查,确保覆盖所有源文件类型:


🏁 Script executed:

#!/bin/bash
# 在 .js 和 .jsx 文件中检查是否使用了 React 16/17 特定 API
rg "React\.version|react-dom.*16|react-dom.*17|\bReact\.render\b|\bfindDOMNode\b|\bunmountComponentAtNode\b" -g '*.js' -g '*.jsx'

Length of output: 131


请标注破坏性变更并提供升级指南

我已在 .ts.tsx.js.jsx 源文件中搜索 React 16/17 特定 API(如 React.renderfindDOMNodeunmountComponentAtNode 等),未发现相关用法,内部代码与 React 18 兼容。请在发布流程中补充以下内容:

  • 在发布说明(CHANGELOG/Release Notes)中明确标记将 React 和 ReactDOM 的最低版本从 >=16.9.0 提升至 >=18.0.0 属于破坏性变更
  • 提供升级指南,说明从 React 16/17 迁移到 React 18 的注意事项、常见问题及示例代码片段
🤖 Prompt for AI Agents
In package.json lines 73 to 76, the peerDependencies for React and ReactDOM have
been raised from >=16.9.0 to >=18.0.0, which is a breaking change. Update the
release notes or CHANGELOG to clearly mark this as a breaking change and add an
upgrade guide section that explains the migration from React 16/17 to React 18,
including key considerations, common issues, and example code snippets to assist
users in upgrading smoothly.

}
26 changes: 8 additions & 18 deletions src/Filler.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as React from 'react';
import ResizeObserver from 'rc-resize-observer';
import ResizeObserver from '@rc-component/resize-observer';
import classNames from 'classnames';

export type InnerProps = Pick<React.HTMLAttributes<HTMLDivElement>, 'role' | 'id'>;
Expand Down Expand Up @@ -28,20 +28,10 @@ interface FillerProps {
/**
* Fill component to provided the scroll content real height.
*/
const Filler = React.forwardRef(
const Filler = React.forwardRef<HTMLDivElement, FillerProps>(
(
{
height,
offsetY,
offsetX,
children,
prefixCls,
onInnerResize,
innerProps,
rtl,
extra,
}: FillerProps,
ref: React.Ref<HTMLDivElement>,
{ height, offsetY, offsetX, children, prefixCls, onInnerResize, innerProps, rtl, extra },
ref,
) => {
let outerStyle: React.CSSProperties = {};

Expand Down Expand Up @@ -80,9 +70,7 @@ const Filler = React.forwardRef(
>
<div
style={innerStyle}
className={classNames({
[`${prefixCls}-holder-inner`]: prefixCls,
})}
className={classNames({ [`${prefixCls}-holder-inner`]: prefixCls })}
ref={ref}
{...innerProps}
>
Expand All @@ -95,6 +83,8 @@ const Filler = React.forwardRef(
},
);

Filler.displayName = 'Filler';
if (process.env.NODE_ENV !== 'production') {
Filler.displayName = 'Filler';
}

export default Filler;
7 changes: 2 additions & 5 deletions src/Item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,8 @@ export interface ItemProps {
}

export function Item({ children, setRef }: ItemProps) {
const refFunc = React.useCallback(node => {
const refFunc = React.useCallback((node: HTMLElement) => {
setRef(node);
}, []);

return React.cloneElement(children, {
ref: refFunc,
});
return React.cloneElement<any>(children, { ref: refFunc });
}
24 changes: 13 additions & 11 deletions src/List.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import classNames from 'classnames';
import type { ResizeObserverProps } from 'rc-resize-observer';
import ResizeObserver from 'rc-resize-observer';
import { useEvent } from 'rc-util';
import useLayoutEffect from 'rc-util/lib/hooks/useLayoutEffect';
import type { ResizeObserverProps } from '@rc-component/resize-observer';
import ResizeObserver from '@rc-component/resize-observer';
import { useEvent } from '@rc-component/util';
import useLayoutEffect from '@rc-component/util/lib/hooks/useLayoutEffect';
import * as React from 'react';
import { useRef, useState } from 'react';
import { flushSync } from 'react-dom';
Expand Down Expand Up @@ -148,9 +148,9 @@ export function RawList<T>(props: ListProps<T>, ref: React.Ref<ListRef>) {

const mergedClassName = classNames(prefixCls, { [`${prefixCls}-rtl`]: isRTL }, className);
const mergedData = data || EMPTY_DATA;
const componentRef = useRef<HTMLDivElement>();
const fillerInnerRef = useRef<HTMLDivElement>();
const containerRef = useRef<HTMLDivElement>();
const componentRef = useRef<HTMLDivElement>(null);
const fillerInnerRef = useRef<HTMLDivElement>(null);
const containerRef = useRef<HTMLDivElement>(null);

// =============================== Item Key ===============================

Expand Down Expand Up @@ -190,7 +190,7 @@ export function RawList<T>(props: ListProps<T>, ref: React.Ref<ListRef>) {
// Put ref here since the range is generate by follow
const rangeRef = useRef({ start: 0, end: mergedData.length });

const diffItemRef = useRef<T>();
const diffItemRef = useRef<T>(null);
const [diffItem] = useDiffItem(mergedData, getKey);
diffItemRef.current = diffItem;

Expand Down Expand Up @@ -309,8 +309,8 @@ export function RawList<T>(props: ListProps<T>, ref: React.Ref<ListRef>) {
};

// Hack on scrollbar to enable flash call
const verticalScrollBarRef = useRef<ScrollBarRef>();
const horizontalScrollBarRef = useRef<ScrollBarRef>();
const verticalScrollBarRef = useRef<ScrollBarRef>(null);
const horizontalScrollBarRef = useRef<ScrollBarRef>(null);

const horizontalScrollBarSpinSize = React.useMemo(
() => getSpinSize(size.width, scrollWidth),
Expand Down Expand Up @@ -675,7 +675,9 @@ export function RawList<T>(props: ListProps<T>, ref: React.Ref<ListRef>) {

const List = React.forwardRef<ListRef, ListProps<any>>(RawList);

List.displayName = 'List';
if (process.env.NODE_ENV !== 'production') {
List.displayName = 'List';
}

export default List as <Item = any>(
props: ListProps<Item> & { ref?: React.Ref<ListRef> },
Expand Down
Loading
Loading