chore: optimize code quality and performance

This commit is contained in:
yyh
2026-01-20 15:54:31 +08:00
parent 53f828f00e
commit cf5e8491df
5 changed files with 47 additions and 32 deletions

View File

@ -1,6 +1,7 @@
'use client'
import * as React from 'react'
import { useMemo } from 'react'
type TreeGuideLinesProps = {
level: number
@ -16,20 +17,20 @@ const TreeGuideLines: React.FC<TreeGuideLinesProps> = ({
indentSize = INDENT_SIZE,
lineOffset = DEFAULT_LINE_OFFSET,
}) => {
if (level === 0)
return null
const guides = useMemo(() => {
if (level === 0)
return null
return (
<>
{Array.from({ length: level }).map((_, i) => (
<div
key={`guide-${i}`}
className="absolute bottom-0 top-0 border-l border-divider-subtle"
style={{ left: `${(i + 1) * indentSize - lineOffset}px` }}
/>
))}
</>
)
return Array.from({ length: level }, (_, i) => (
<div
key={`guide-${i}`}
className="absolute bottom-0 top-0 border-l border-divider-subtle"
style={{ left: `${(i + 1) * indentSize - lineOffset}px` }}
/>
))
}, [level, indentSize, lineOffset])
return guides
}
export default React.memo(TreeGuideLines)

View File

@ -50,14 +50,16 @@ export function useCreateOperations({
}
try {
for (const file of files) {
await createFile.mutateAsync({
appId,
name: file.name,
file,
parentId,
})
}
await Promise.all(
files.map(file =>
createFile.mutateAsync({
appId,
name: file.name,
file,
parentId,
}),
),
)
Toast.notify({
type: 'success',

View File

@ -1,4 +1,4 @@
import { useCallback, useRef } from 'react'
import { useCallback, useEffect, useRef } from 'react'
type UseDelayedClickOptions = {
delay?: number
@ -18,6 +18,14 @@ export function useDelayedClick({
}: UseDelayedClickOptions) {
const timeoutRef = useRef<NodeJS.Timeout | null>(null)
// Cleanup timeout on unmount to prevent state updates on unmounted components
useEffect(() => {
return () => {
if (timeoutRef.current)
clearTimeout(timeoutRef.current)
}
}, [])
const handleClick = useCallback(() => {
if (timeoutRef.current)
clearTimeout(timeoutRef.current)

View File

@ -73,13 +73,15 @@ export function usePasteOperation({
isPastingRef.current = true
try {
for (const nodeId of nodeIdsArray) {
await moveNode.mutateAsync({
appId,
nodeId,
payload: { parent_id: targetParentId },
})
}
await Promise.all(
nodeIdsArray.map(nodeId =>
moveNode.mutateAsync({
appId,
nodeId,
payload: { parent_id: targetParentId },
}),
),
)
storeApi.getState().clearClipboard()

View File

@ -3,7 +3,7 @@
import type { NodeApi } from 'react-arborist'
import type { TreeNodeData } from '../type'
import { throttle } from 'es-toolkit/function'
import { useCallback, useMemo } from 'react'
import { useCallback, useMemo, useRef } from 'react'
import { useWorkflowStore } from '@/app/components/workflow/store'
import { useDelayedClick } from './use-delayed-click'
@ -24,10 +24,12 @@ export function useTreeNodeHandlers({
}: UseTreeNodeHandlersOptions): UseTreeNodeHandlersReturn {
const storeApi = useWorkflowStore()
const isFolder = node.data.node_type === 'folder'
const nodeRef = useRef(node)
nodeRef.current = node
const throttledToggle = useMemo(
() => throttle(() => node.toggle(), 300, { edges: ['leading'] }),
[node],
() => throttle(() => nodeRef.current.toggle(), 300, { edges: ['leading'] }),
[],
)
const openFilePreview = useCallback(() => {