| 113 | onChange(changedValue); |
| 114 | }; |
| 115 | |
| 116 | -- const handleOk = (nextResult = result) => { |
| 116 | ++ const handleOk = (nextResult) => { |
| 117 | ++ let list = EMPTY_ARRAY; |
| 118 | ++ if (Array.isArray(nextResult)) { |
| 119 | ++ list = nextResult; |
| 120 | ++ } else if (Array.isArray(result)) { |
| 121 | ++ list = result; |
| 122 | ++ } |
| 123 | setVisible(false); |
| 124 | -- setSource(nextResult); |
| 125 | -- triggerChange(nextResult); |
| 124 | ++ setSource(list); |
| 125 | ++ triggerChange(list); |
| 126 | }; |
| ... | @@ -142,7 +148,8 @@ renderItem 消费端防御 @@ |
| 147 | recordTypes.forEach((r, index) => { |
| 148 | -- const selectedRecords = source?.filter(t => t.type === r) || []; |
| 148 | ++ const safeSource = Array.isArray(source) ? source : EMPTY_ARRAY; |
| 149 | ++ const selectedRecords = safeSource.filter(t => t.type === r); |
| 150 | if (recordType && selectedRecords.length === 0) return; |
| ... | @@ -190,7 +197,7 @@ Dialog onOk 调用点截断 @@ |
| 196 | className="link-dialog common-Dialog-style" |
| 197 | visible={visible} |
| 198 | -- onOk={handleOk} |
| 198 | ++ onOk={() => handleOk(result)} |
| 199 | onClose={handleCancel} |
| 200 | okText="导入" |
onOk={() => handleOk(result)} 属于“头痛医头”的点状补丁(Symptom Fix)。它把系统的健壮性完全押注在「唯一一个 JSX 属性绝对不出错」的假设上。一旦有第二处调用、父组件异常传参或未来组件重构,脆弱的防线会瞬间瓦解,白屏必定复发。
(nextResult = result) => ...。handleOk 本身依然毫无防备。任何地方一旦传递 null、0、false 或其他非数组对象,默认值立即失效,脏对象直接写入 state!
afterClose={() => handleCheckbox(false, item, handleOk)}handleOk 被作为高阶函数回调 cb 传入了 handleCheckbox!handleOk 内部紧接着执行了 triggerChange(nextResult),直接驱动外部 Form 的 onChange。| 可能发生的真实场景 | 方案 A:只改 onOk 这一处 | 方案 B:当前提交的完整修复 (3处) |
|---|---|---|
| 场景 1:用户点击弹窗「导入」按钮 | ✓ 解决(不再把事件传给 handleOk) | ✓ 彻底解决 |
| 场景 2:未来他人重构或组件升级 (例如 Dialog 升级、或抽取了通用弹窗函数) |
✗ 极易穿透 如果新人写了 onOk={handleOk},白屏立即原样复发。 |
✓ 免疫handleOk 入口 Array.isArray 自动拦截并清洗降级。 |
| 场景 3:调用方传入异常非数组数据 (如 afterClose 回调、接口异常返回 null 等) |
✗ 崩溃 直接写进 source,导致 renderItem 崩溃白屏。 |
✓ 免疫handleOk 强行归一化为安全数组。 |
| 场景 4:消费端 renderItem 遍历 (不管 state 因任何原因异常蜕变) |
✗ 脆弱source?.filter 遇到非数组 Object 必抛 TypeError,React 整树卸载白屏。 |
✓ 免疫safeSource = Array.isArray ? source : [],保证 100% 数组安全,绝不整页白屏。 |
safeSource 守卫将不可逆的整页崩溃降级为了局部的安全降级。