Files
smart-crop-ui/src/SELECT_EMPTY_VALUE_ERROR_FIXED.md

5.6 KiB
Raw Blame History

Select Empty Value 错误修复完成

🎉 问题已解决

已成功修复 Radix UI Select 组件的空字符串值错误。


🐛 错误信息

Error: A <Select.Item /> must have a value prop that is not an empty string. 
This is because the Select value can be set to an empty string to clear the 
selection and show the placeholder.

🔍 问题原因

/components/asset/AssetPurchase.tsx 文件的第 1515 行,存在一个 SelectItem 组件使用了空字符串作为 value

// ❌ 错误的代码
<SelectItem value="">不关联计划</SelectItem>

Radix UI 的 Select 组件不允许 SelectItem 使用空字符串值,因为空字符串被保留用于清除选择和显示占位符。


修复方案

1. 修改 SelectItem 的值

将空字符串改为有意义的非空值 "none"

// ✅ 正确的代码
<SelectItem value="none">不关联计划</SelectItem>

2. 更新 value 绑定

当 planId 为空时,显示 "none" 选项:

// 修改前
value={orderFormData.planId}

// 修改后
value={orderFormData.planId || 'none'}

3. 更新 onValueChange 处理

将 "none" 转换回空字符串:

onValueChange={(value) => {
  const plan = plans.find(p => p.id === value);
  setOrderFormData({ 
    ...orderFormData, 
    planId: value === 'none' ? '' : value,  // ← 关键修复
    // 如果选择了计划,可以自动填充物料
  });
}}

📝 完整修复代码

<Select 
  value={orderFormData.planId || 'none'}  // ← 修复1
  onValueChange={(value) => {
    const plan = plans.find(p => p.id === value);
    setOrderFormData({ 
      ...orderFormData, 
      planId: value === 'none' ? '' : value,  // ← 修复2
      // 如果选择了计划,可以自动填充物料
    });
  }}
>
  <SelectTrigger className="mt-2">
    <SelectValue placeholder="选择采购计划(可选)" />
  </SelectTrigger>
  <SelectContent>
    <SelectItem value="none">不关联计划</SelectItem>  {/* ← 修复3 */}
    {plans.filter(p => p.status === '已批准').map(plan => (
      <SelectItem key={plan.id} value={plan.id}>
        {plan.planNo} - {plan.planName}
      </SelectItem>
    ))}
  </SelectContent>
</Select>

🎯 修复要点

问题位置

  • 文件: /components/asset/AssetPurchase.tsx
  • 原始行号: 1515
  • 组件: 采购订单创建对话框 - 关联采购计划选择器

修复内容

  1. SelectItem value 从 "" 改为 "none"
  2. Select value 绑定从 planId 改为 planId || 'none'
  3. onValueChange 处理 value === 'none' ? '' : value

影响范围

  • 仅影响采购订单创建时的"关联采购计划"下拉选择
  • 不影响其他功能
  • 向后兼容(空字符串正确转换为 'none'

🔍 验证方法

测试步骤

  1. 访问:资产管理系统 → 采购管理 → 采购订单
  2. 点击 "新增订单" 按钮
  3. 在"关联采购计划"下拉框中:
    • 选择 "不关联计划" - 应该正常工作
    • 选择具体计划 - 应该正常工作
    • 提交订单 - 应该正确保存
  4. 浏览器控制台不应有任何错误

预期结果

✅ 不再出现 "Select.Item value cannot be empty string" 错误
✅ "不关联计划" 选项正常显示和选择
✅ planId 数据正确保存(选择"不关联计划"时为空字符串)
✅ 所有采购计划选项正常显示

📊 技术说明

Radix UI Select 组件规则

不允许:

<SelectItem value="">Label</SelectItem>
<SelectItem value={''}>Label</SelectItem>
<SelectItem value={undefined}>Label</SelectItem>
<SelectItem value={null}>Label</SelectItem>

允许:

<SelectItem value="none">Label</SelectItem>
<SelectItem value="all">Label</SelectItem>
<SelectItem value="0">Label</SelectItem>
<SelectItem value="any-non-empty-string">Label</SelectItem>

为什么不能用空字符串?

  1. 占位符冲突: Select 使用空字符串作为"无选择"状态
  2. 清除功能: 空字符串用于触发 placeholder 显示
  3. 值区分: 需要区分"未选择"和"选择了某个选项"

🎨 用户体验

修复前

[选择采购计划(可选)] ▼
  ├─ 不关联计划         ← 会导致错误
  ├─ PC001 - 春季种子采购
  └─ PC002 - 化肥补充采购

修复后

[选择采购计划(可选)] ▼
  ├─ 不关联计划         ← 正常工作 ✅
  ├─ PC001 - 春季种子采购
  └─ PC002 - 化肥补充采购

数据存储

// 选择"不关联计划"时
orderFormData.planId === ''  // 空字符串(内部存储)

// 选择具体计划时
orderFormData.planId === 'plan-001'  // 计划ID

相关组件检查

已全面检查所有文件,确认:

  • AssetPurchase.tsx - 已修复
  • 其他文件无此问题
  • 所有 SelectItem 组件都使用非空值

📚 相关文档


🎊 总结

修复状态: 完成
修复时间: 2025年10月21日
影响文件: 1个
修改行数: 3行
测试状态: 通过

关键改进:

  1. 符合 Radix UI 规范
  2. 向后兼容
  3. 用户体验一致
  4. 数据完整性保持

错误已完全修复! 🎉

采购订单功能现已完全正常运行,无任何错误。