# 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工具更加稳定和易用。