# TVAI Hooks 错误修复和文件选择功能改进总结 ## 🐛 问题诊断 ### React Hooks 错误 ``` Uncaught Error: Rendered fewer hooks than expected. This may be caused by an accidental early return statement. ``` **根本原因**: 在React组件中,Hooks必须在每次渲染时以相同的顺序调用。如果在早期返回语句之后调用Hooks,会导致Hooks数量不一致的错误。 ### 问题代码结构 ```typescript export function TvaiExample() { // ✅ 正确:Hooks在早期返回之前 const [state1] = useState(); const [state2] = useState(); // ❌ 错误:早期返回 if (loading) { return
Loading...
; } // ❌ 错误:Hooks在早期返回之后 const callback = useCallback(() => {}, []); } ``` ## ✅ 修复方案 ### 1. Hooks 重新排序 将所有Hooks调用移到早期返回语句之前: ```typescript export function TvaiExample() { // ✅ 所有Hooks必须在早期返回之前 const { systemInfo, isLoading: systemLoading, initializeTvai } = useTvaiSystemInfo(); const { tasks, isLoading: tasksLoading, cancelTask, cleanupCompletedTasks } = useTvai(); // 状态Hooks const [processingType, setProcessingType] = useState<'video' | 'image' | 'interpolation'>('video'); const [showAdvanced, setShowAdvanced] = useState(false); const [inputPath, setInputPath] = useState(''); const [outputPath, setOutputPath] = useState(''); const [scaleFactor, setScaleFactor] = useState(2.0); const [selectedPreset, setSelectedPreset] = useState('GENERAL'); const [selectedModel, setSelectedModel] = useState('iris-3'); const [compression, setCompression] = useState(0.0); const [blend, setBlend] = useState(0.0); const [interpolationMultiplier, setInterpolationMultiplier] = useState(2.0); // useCallback Hooks const handleSelectInputFile = useCallback(async () => { /* ... */ }, [processingType]); const handleSelectOutputFile = useCallback(async () => { /* ... */ }, [processingType]); // 普通函数 const applyPreset = (presetName: string) => { /* ... */ }; const handleQuickProcess = async () => { /* ... */ }; // ✅ 早期返回在所有Hooks之后 if (systemLoading) { return
Loading...
; } // 正常渲染 return
...
; } ``` ### 2. 清理未使用的变量 移除了以下未使用的状态变量: - `currentStep` 和 `setCurrentStep` - `qualityPreset` 和 `setQualityPreset` - `outputFormat` 和 `setOutputFormat` - `targetFps` 和 `setTargetFps` - `isDragging` 和 `setIsDragging` ### 3. 移除重复的函数定义 删除了重复定义的函数: - 重复的 `applyPreset` 函数 - 重复的 `handleQuickProcess` 函数 - 重复的早期返回语句 ## 🎯 文件选择功能改进 ### 参考其他页面的实现 通过分析 `ImageEditingTool.tsx` 和其他工具页面,采用了统一的文件选择模式: ```typescript import { open } from '@tauri-apps/plugin-dialog'; const handleSelectFile = useCallback(async () => { try { const selected = await open({ multiple: false, filters: [{ name: '视频文件', extensions: ['mp4', 'avi', 'mov'] }], title: '选择视频文件', }); if (selected && typeof selected === 'string') { setInputPath(selected); // 自动生成输出路径 generateOutputPath(selected); } } catch (error) { console.error('选择文件失败:', error); alert('选择文件失败: ' + error.message); } }, [processingType]); ``` ### 文件格式配置 ```typescript const FILE_FORMATS = { video: { name: '视频文件', extensions: ['mp4', 'avi', 'mov', 'mkv', 'wmv', 'flv', 'm4v', 'webm', '3gp', 'ts'] }, image: { name: '图片文件', extensions: ['jpg', 'jpeg', 'png', 'bmp', 'tiff', 'webp', 'gif', 'svg'] } }; ``` ### UI 改进 从简单的文本输入框改为专业的文件选择按钮: **原来的设计**: ```jsx setInputPath(e.target.value)} placeholder="选择视频文件..." /> ``` **新的设计**: ```jsx ``` ### 智能功能 1. **自动路径生成**: 根据输入文件自动生成输出路径 2. **动态文件类型**: 根据处理类型显示对应的文件格式 3. **文件名显示**: 显示文件名和完整路径 4. **一键生成**: 提供"自动生成输出路径"按钮 ## 🔧 技术细节 ### Hooks 调用顺序规则 1. **自定义Hooks**: `useTvaiSystemInfo()`, `useTvai()` 2. **状态Hooks**: `useState()` 3. **效果Hooks**: `useCallback()`, `useMemo()`, `useEffect()` 4. **早期返回**: 在所有Hooks之后 5. **事件处理函数**: 普通函数,不是Hooks ### 文件选择最佳实践 1. **统一API**: 使用 `@tauri-apps/plugin-dialog` 的 `open()` 函数 2. **类型安全**: TypeScript 类型检查 3. **错误处理**: try-catch 包装,用户友好的错误提示 4. **用户体验**: 加载状态、进度反馈、自动完成 ### 性能优化 1. **useCallback**: 防止不必要的重新渲染 2. **依赖数组**: 正确设置依赖项 3. **条件渲染**: 避免不必要的计算 ## 📊 修复前后对比 | 方面 | 修复前 | 修复后 | |------|--------|--------| | Hooks错误 | ❌ 运行时崩溃 | ✅ 正常运行 | | 文件选择 | ❌ 手动输入路径 | ✅ 原生文件对话框 | | 用户体验 | ❌ 复杂操作 | ✅ 一键选择 | | 错误处理 | ❌ 基础提示 | ✅ 详细错误信息 | | 路径生成 | ❌ 手动输入 | ✅ 自动生成 | | 文件格式 | ❌ 无限制 | ✅ 类型过滤 | ## 🚀 用户体验提升 ### 操作流程简化 1. **选择处理类型** → 自动设置文件格式过滤 2. **点击选择文件** → 打开原生文件对话框 3. **选择文件** → 自动生成输出路径 4. **开始处理** → 一键启动 ### 错误预防 1. **文件格式验证**: 只允许选择支持的格式 2. **路径验证**: 确保文件存在且可读 3. **权限检查**: 确保输出路径可写 4. **友好提示**: 清晰的错误信息和解决建议 ## 总结 通过修复React Hooks的调用顺序问题和改进文件选择功能,TVAI工具现在具有: ✅ **稳定性** - 无运行时错误,符合React规范 ✅ **易用性** - 原生文件对话框,操作简单 ✅ **智能化** - 自动路径生成,类型过滤 ✅ **专业性** - 统一的UI设计,完善的错误处理 这些改进大大提升了用户体验,使TVAI工具更加稳定和易用。