当用户调整滑动参数导致图像加载错误后,再次调整滑动参数(即使调整到正常范围),图像也不会重新加载和刷新。
ImageViewerErrorBoundary 捕获错误,显示错误 UIErrorBoundary 继续显示错误界面 ❌滑块调整 → updateViewerUrl() → viewerUrlMap 更新
↓
ViewerContainer 获取 actualUrl(新 URL)
↓
传递给 StackViewerWithErrorBoundary(props.imageUrls 变化)
↓
但 ErrorBoundary 处于错误状态(hasError = true)
↓
ErrorBoundary 只渲染错误 UI,不渲染子组件 StackViewer
↓
即使 props 变化,StackViewer 也不会重新渲染和加载图像
React ErrorBoundary 的行为:
getDerivedStateFromError 或 componentDidCatch 被触发hasError: true)handleRetry() 才会重置错误状态这导致的问题:
imageUrls prop 变化了核心思路:当图像 URL 变化时,通过改变 key 属性强制 React 卸载旧组件并挂载新组件。
在 src/pages/view/components/ViewerContainer.tsx 中:
const renderViewers = (start: number, end: number) => {
return imageUrls.slice(start, end).map((originalUrl, index) => {
const actualUrl = getActualUrl(originalUrl);
return (
<div
key={start + index}
onClick={(event) => handleSelectViewer(originalUrl, event)}
>
<StackViewerWithErrorBoundary
key={actualUrl} // ✅ 关键修改:使用 actualUrl 作为 key
imageIndex={0}
imageUrls={[actualUrl]}
viewportId={getViewportIdByUrl(originalUrl) as string}
renderingEngineId={renderingEngineId}
selected={selectedViewerUrls.includes(originalUrl)}
/>
</div>
);
});
};
参数调整触发 URL 变化
滑块调整 → buildProcessedDcmUrl() → 新 URL(带参数)
→ updateViewerUrl() → viewerUrlMap 更新
→ actualUrl 变化
key 变化触发组件重新挂载
actualUrl 变化 → key 变化
→ React 卸载旧的 ErrorBoundary + StackViewer
→ 挂载新的 ErrorBoundary + StackViewer
→ 新实例有全新状态(hasError = false)
→ StackViewer 正常加载图像
自动从错误中恢复
src/pages/view/components/ViewerContainer.tsx - 主要修改src/pages/view/components/viewers/ImageViewerErrorBoundary.tsx - ErrorBoundary 实现src/pages/view/components/viewers/stack.image.viewer.tsx - StackViewer 实现src/pages/view/components/SliderAdjustmentPanel.tsx - 滑动参数面板我们使用 actualUrl 作为 key,而不是其他值,原因:
actualUrl 包含所有参数信息
避免不必要的重新挂载
便于调试
通过将 StackViewerWithErrorBoundary 的 key 从固定的索引值改为动态的 actualUrl,我们成功实现了:
这是一个优雅且符合 React 最佳实践的解决方案。
2025-01-23