6.1 KiB
6.1 KiB
✅ Select 空字符串错误修复
🔧 问题描述
Radix UI 的 Select 组件报错:
Error: A <Select.Item /> must have a value prop that is not an empty string.
原因: Radix UI 的 Select 组件不允许 SelectItem 使用空字符串 "" 作为 value,因为空字符串被保留用于清除选择和显示占位符。
📋 修复文件
修复了以下文件中的所有空字符串值:
1. /components/machinery/operation/PlanDispatch.tsx
- ✅ 路线方案选择器
2. /components/machinery/scheduling/TaskForm.tsx
- ✅ 农机设备选择器
- ✅ 驾驶员选择器
🔨 具体修复内容
PlanDispatch.tsx
修复前
<SelectItem value="">不选择路线</SelectItem>
const [selectedRoute, setSelectedRoute] = useState<string>('');
修复后
<SelectItem value="none">不选择路线</SelectItem>
const [selectedRoute, setSelectedRoute] = useState<string>('none');
逻辑处理
// 下发逻辑中判断
routePlanId: selectedRoute && selectedRoute !== 'none' ? selectedRoute : undefined,
routePlanName: selectedRouteData?.name || undefined,
TaskForm.tsx
修复前
<SelectItem value="">暂不分配</SelectItem>
const [selectedMachinery, setSelectedMachinery] = useState<string>('');
const [selectedDriver, setSelectedDriver] = useState<string>('');
修复后
<SelectItem value="unassigned">暂不分配</SelectItem>
const [selectedMachinery, setSelectedMachinery] = useState<string>('unassigned');
const [selectedDriver, setSelectedDriver] = useState<string>('unassigned');
逻辑处理
// 提交时判断
const selectedMachineryData = selectedMachinery && selectedMachinery !== 'unassigned'
? machinery.find(m => m.id === selectedMachinery)
: null;
const selectedDriverData = selectedDriver && selectedDriver !== 'unassigned'
? drivers.find(d => d.id === selectedDriver)
: null;
const task: Partial<Task> = {
machineryId: selectedMachinery && selectedMachinery !== 'unassigned' ? selectedMachinery : null,
driverId: selectedDriver && selectedDriver !== 'unassigned' ? selectedDriver : null,
};
警告提示更新
// 修复前
{!selectedMachinery && !selectedDriver && (
<div>...</div>
)}
// 修复后
{(selectedMachinery === 'unassigned' || !selectedMachinery) &&
(selectedDriver === 'unassigned' || !selectedDriver) && (
<div>...</div>
)}
📊 修复汇总
修改统计
| 文件 | SelectItem 修复 | 状态初始化 | 逻辑处理 |
|---|---|---|---|
| PlanDispatch.tsx | 1处 | 1处 | 2处 |
| TaskForm.tsx | 2处 | 2处 | 4处 |
| 总计 | 3处 | 3处 | 6处 |
替换规则
| 原值 | 新值 | 用途 |
|---|---|---|
"" |
"none" |
不选择路线 |
"" |
"unassigned" |
暂不分配资源 |
✅ 验证结果
测试场景
1. PlanDispatch - 路线选择
✅ 选择"不选择路线" → value = "none"
✅ 下发时正确判断为无路线
✅ 切换到其他路线正常工作
✅ 不再报错
2. TaskForm - 农机选择
✅ 选择"暂不分配" → value = "unassigned"
✅ 提交时 machineryId = null
✅ 切换到具体农机正常工作
✅ 不再报错
3. TaskForm - 驾驶员选择
✅ 选择"暂不分配" → value = "unassigned"
✅ 提交时 driverId = null
✅ 切换到具体驾驶员正常工作
✅ 不再报错
4. 警告提示
✅ 未分配资源时正确显示警告
✅ 分配资源后警告消失
✅ 逻辑判断正确
🎯 最佳实践
Radix UI Select 使用规范
❌ 不要这样做
<SelectItem value="">请选择</SelectItem>
<SelectItem value="">无</SelectItem>
<SelectItem value="">不限</SelectItem>
✅ 应该这样做
<SelectItem value="none">请选择</SelectItem>
<SelectItem value="null">无</SelectItem>
<SelectItem value="unlimited">不限</SelectItem>
处理逻辑建议
// 1. 使用有意义的特殊值
const UNASSIGNED = 'unassigned';
const NONE = 'none';
// 2. 初始化时使用特殊值
const [value, setValue] = useState<string>(UNASSIGNED);
// 3. 判断时检查特殊值
const isSelected = value && value !== UNASSIGNED;
// 4. 提交时转换为实际值
const finalValue = value !== UNASSIGNED ? value : null;
📝 代码示例
完整的 Select 组件示例
import { useState } from 'react';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from './ui/select';
export function MySelect() {
const [value, setValue] = useState<string>('unassigned');
const handleSubmit = () => {
// 转换特殊值为 null
const finalValue = value !== 'unassigned' ? value : null;
console.log('提交值:', finalValue);
};
return (
<Select value={value} onValueChange={setValue}>
<SelectTrigger>
<SelectValue placeholder="请选择" />
</SelectTrigger>
<SelectContent>
<SelectItem value="unassigned">暂不分配</SelectItem>
<SelectItem value="option1">选项1</SelectItem>
<SelectItem value="option2">选项2</SelectItem>
</SelectContent>
</Select>
);
}
🔍 检查清单
在项目中使用 Select 组件时,请检查:
- SelectItem 的 value 不是空字符串
"" - 使用有意义的特殊值(如
"none","unassigned") - 初始化状态使用特殊值而非空字符串
- 提交/处理逻辑中正确判断特殊值
- 条件渲染中考虑特殊值
- 不要使用
null或undefined作为 SelectItem value
🎉 结论
所有 Select 空字符串错误已完全修复!
修复成果
- ✅ 移除所有空字符串 SelectItem value
- ✅ 使用有意义的特殊值替代
- ✅ 更新所有相关逻辑判断
- ✅ 验证所有功能正常工作
- ✅ 不再有 Radix UI 错误
影响范围
- ✅ 作业方案下发功能 - 正常
- ✅ 任务创建/编辑功能 - 正常
- ✅ 资源分配功能 - 正常
- ✅ 所有 Select 组件 - 正常
修复时间: 2025-10-17
状态: ✅ 完成
测试: ✅ 通过