React 17 集成 Mirador IIIF Viewer 报错问题求助
React集成Mirador IIIF Viewer运行异常的排查与修复方案
核心问题排查及修复步骤
1. 实例重复创建与内存泄漏
你的代码未在组件卸载时清理Mirador实例,也未限制重复初始化,导致组件重渲染时多次创建实例引发DOM冲突。
修复方案:
用ref存储Mirador实例,在组件卸载时调用destroy()方法清理:
const miradorInstanceRef = useRef(null); useEffect(() => { const container = miradorContainer.current; if (!container || miradorInstanceRef.current) return; const miradorInstance = Mirador.viewer({ id: 'mirador', // 你的配置项 }, container); miradorInstanceRef.current = miradorInstance; // 组件卸载时清理实例 return () => { if (miradorInstanceRef.current) { miradorInstanceRef.current.destroy(); miradorInstanceRef.current = null; } }; }, []);
2. State订阅未取消导致报错
代码中订阅了Mirador的store,但未在组件卸载时取消订阅,组件销毁后仍尝试更新状态会引发异常。
修复方案:
保存订阅返回的取消函数,在清理阶段调用:
useEffect(() => { // ... 初始化Mirador代码 ... const unsubscribe = miradorInstance.store.subscribe(() => { const state = miradorInstance.store.getState(); setViewerState(state); }); return () => { unsubscribe(); // 取消订阅 if (miradorInstanceRef.current) { miradorInstanceRef.current.destroy(); miradorInstanceRef.current = null; } }; }, []);
3. 容器元素存在性校验缺失
初始化Mirador前未确认容器元素已挂载到DOM,可能因miradorContainer.current为null导致初始化失败。
修复方案:
添加容器存在性判断:
useEffect(() => { const container = miradorContainer.current; if (!container) return; // 容器不存在则终止执行 // 初始化Mirador逻辑... }, []);
4. 配置项有效性验证
检查windows数组中的manifest URL是否为可访问的有效IIIF资源,可直接在浏览器中访问URL验证格式和可用性。
完整修复后的代码示例
import React, { useState, useEffect, useRef } from 'react'; import ReactDOM from 'react-dom/client'; import Mirador from 'mirador/dist/es/src/index'; import 'mirador/dist/es/src/styles/mirador.css'; const App = () => { const [viewerState, setViewerState] = useState(null); const miradorContainer = useRef(null); const miradorInstanceRef = useRef(null); useEffect(() => { const container = miradorContainer.current; if (!container || miradorInstanceRef.current) return; const miradorInstance = Mirador.viewer( { id: 'mirador', windows: [ { manifestId: 'https://iiif.lib.ncsu.edu/iiif/0052544/manifest.json', thumbnailNavigationPosition: 'bottom', }, ], }, container ); miradorInstanceRef.current = miradorInstance; const unsubscribe = miradorInstance.store.subscribe(() => { const state = miradorInstance.store.getState(); setViewerState(state); }); return () => { unsubscribe(); miradorInstanceRef.current.destroy(); miradorInstanceRef.current = null; }; }, []); return ( <div> <h1>Mirador in React</h1> <div ref={miradorContainer} style={{ height: '80vh' }} /> {viewerState && ( <pre>{JSON.stringify(viewerState, null, 2)}</pre> )} </div> ); }; const root = ReactDOM.createRoot(document.getElementById('root')); root.render(<App />);
内容的提问来源于stack exchange,提问作者keerti
相关产品推荐
相关产品推荐

