-
-
Notifications
You must be signed in to change notification settings - Fork 278
fix: batch remove laggy #757
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
## debug | ||
|
||
|
||
<code src="../examples/debug.tsx"></code> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import Form, { Field } from 'rc-field-form'; | ||
import React from 'react'; | ||
|
||
function WatchCom({ name }: { name: number }) { | ||
const data = Form.useWatch(name); | ||
return data; | ||
} | ||
|
||
export default function App() { | ||
const [form] = Form.useForm(); | ||
const [open, setOpen] = React.useState<boolean>(true); | ||
|
||
const data = React.useMemo(() => { | ||
return Array.from({ length: 1 * 500 }).map((_, i) => ({ | ||
key: i, | ||
name: `Edward King ${i}`, | ||
age: 32, | ||
address: `London, Park Lane no. ${i}`, | ||
})); | ||
}, []); | ||
|
||
return ( | ||
<Form form={form}> | ||
<div className="App"> | ||
{/* When I made the switch, it was very laggy */} | ||
<button | ||
onClick={() => { | ||
setOpen(!open); | ||
}} | ||
> | ||
Switch | ||
</button> | ||
<WatchCom name={0} /> | ||
<WatchCom name={1} /> | ||
{open ? ( | ||
<div className="flex gap-[5px] flex-wrap"> | ||
{data?.map(item => { | ||
return ( | ||
<Field key={item.name} name={item.name}> | ||
<input /> | ||
</Field> | ||
); | ||
})} | ||
</div> | ||
) : ( | ||
<h2>some thing</h2> | ||
)} | ||
</div> | ||
</Form> | ||
); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import * as React from 'react'; | ||
|
||
export type BatchTask = (key: string, callback: VoidFunction) => void; | ||
|
||
export interface BatchUpdateRef { | ||
batch: BatchTask; | ||
} | ||
|
||
const BatchUpdate = React.forwardRef<BatchUpdateRef>((_, ref) => { | ||
const [batchInfo, setBatchInfo] = React.useState<Record<string, VoidFunction>>({}); | ||
|
||
React.useLayoutEffect(() => { | ||
const keys = Object.keys(batchInfo); | ||
if (keys.length) { | ||
keys.forEach(key => { | ||
batchInfo[key]?.(); | ||
}); | ||
setBatchInfo({}); | ||
} | ||
}, [batchInfo]); | ||
|
||
React.useImperativeHandle(ref, () => ({ | ||
batch: (key, callback) => { | ||
setBatchInfo(ori => ({ | ||
...ori, | ||
[key]: callback, | ||
})); | ||
}, | ||
})); | ||
|
||
return null; | ||
}); | ||
|
||
export default BatchUpdate; |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -38,6 +38,7 @@ import { | |||||||||||||||||||||||||||||||||||||||||||||||||||
matchNamePath, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
setValue, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
} from './utils/valueUtil'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
import type { BatchTask } from './BatchUpdate'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
type InvalidateFieldEntity = { INVALIDATE_NAME_PATH: InternalNamePath }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -119,6 +120,7 @@ export class FormStore { | |||||||||||||||||||||||||||||||||||||||||||||||||||
setPreserve: this.setPreserve, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
getInitialValue: this.getInitialValue, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
registerWatch: this.registerWatch, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
setBatchUpdate: this.setBatchUpdate, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -214,6 +216,27 @@ export class FormStore { | |||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
private notifyWatchNamePathList: InternalNamePath[] = []; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
private batchNotifyWatch = (namePath: InternalNamePath) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
this.notifyWatchNamePathList.push(namePath); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
this.batch('notifyWatch', () => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
this.notifyWatch(this.notifyWatchNamePathList); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
this.notifyWatchNamePathList = []; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
// ============================= Batch ============================ | ||||||||||||||||||||||||||||||||||||||||||||||||||||
private batchUpdate: BatchTask; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
private setBatchUpdate = (batchUpdate: BatchTask) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
this.batchUpdate = batchUpdate; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
// Batch call the task, only last will be called | ||||||||||||||||||||||||||||||||||||||||||||||||||||
private batch = (key: string, callback: VoidFunction) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
this.batchUpdate(key, callback); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+229
to
+238
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 批量更新实现需要添加空值检查。
建议添加空值检查: // Batch call the task, only last will be called
private batch = (key: string, callback: VoidFunction) => {
+ if (!this.batchUpdate) {
+ // 如果批量更新函数尚未设置,直接执行回调
+ callback();
+ return;
+ }
this.batchUpdate(key, callback);
}; 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
// ========================== Dev Warning ========================= | ||||||||||||||||||||||||||||||||||||||||||||||||||||
private timeoutId: any = null; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -642,7 +665,7 @@ export class FormStore { | |||||||||||||||||||||||||||||||||||||||||||||||||||
private registerField = (entity: FieldEntity) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
this.fieldEntities.push(entity); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
const namePath = entity.getNamePath(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
this.notifyWatch([namePath]); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
this.batchNotifyWatch(namePath); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
zombieJ marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
// Set initial values | ||||||||||||||||||||||||||||||||||||||||||||||||||||
if (entity.props.initialValue !== undefined) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -682,7 +705,7 @@ export class FormStore { | |||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
this.notifyWatch([namePath]); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
this.batchNotifyWatch(namePath); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Uh oh!
There was an error while loading. Please reload this page.