mirror of
https://github.com/Dvorinka/MyClubServer.git
synced 2026-06-03 18:22:57 +00:00
3.2 KiB
3.2 KiB
Quill.js Emitter Error Fix
Issue
Uncaught TypeError: can't access property "emit", this.emitter is undefined
This error occurred in CustomRichEditor.tsx when Quill.js tried to initialize or perform operations before its internal emitter was ready.
Root Cause
- Unstable module configuration - The
handleImageUploadcallback was included inquillModulesdependencies, causing the modules object to recreate on every render - Missing initialization guards - Code attempted to access Quill editor methods before the editor was fully initialized
- Concurrent DOM mutations - MutationObserver showed Quill was initializing while DOM was being modified
Solution Applied
1. Stabilized Image Upload Handler
Before:
const handleImageUpload = useCallback(() => { ... }, []);
const quillModules = useMemo(() => ({
toolbar: {
handlers: {
image: onImageUpload ? handleImageUpload : undefined,
},
},
}), [toolbarConfig, onImageUpload, handleImageUpload]); // handleImageUpload caused recreation
After:
const handleImageUploadRef = useRef<() => void>();
useEffect(() => {
handleImageUploadRef.current = () => { ... };
});
const quillModules = useMemo(() => ({
toolbar: {
handlers: {
image: onImageUpload ? () => handleImageUploadRef.current?.() : undefined,
},
},
}), [toolbarConfig, onImageUpload]); // Only stable dependencies
2. Added Emitter Safety Checks
Before:
const quill = quillRef.current?.getEditor();
if (quill) {
quill.focus();
// ... operations
}
After:
const quill = quillRef.current?.getEditor();
if (quill && quill.root && quill.emitter) {
setTimeout(() => {
// Double-check Quill is still valid
if (!quill || !quill.emitter) {
toast({ title: 'Editor není připraven', ... });
return;
}
// ... operations
}, 100);
} else {
toast({ title: 'Editor není připraven', ... });
}
3. Added Stable Key to ReactQuill
<ReactQuill
key={`quill-${readOnly ? 'readonly' : 'edit'}`}
// ... other props
/>
This prevents unnecessary remounting while allowing controlled reinitialization when mode changes.
4. Protected Image Manipulation Effect
useEffect(() => {
const editor = quillRef.current?.getEditor();
if (!editor || !editor.root || !editor.emitter || readOnly) return;
// ... event handlers
}, [readOnly, toast]);
Benefits
- ✅ Prevents Quill from reinitializing on every render
- ✅ Ensures operations only happen when editor is fully ready
- ✅ Provides user feedback when editor isn't ready
- ✅ Maintains stable component lifecycle
- ✅ Fixes the "this.emitter is undefined" error
Testing
- Create a new article in admin panel
- Click "Vložit obrázek" or use toolbar image button
- Select and crop an image
- Verify image inserts without errors
- Test image editing features (resize, filters, alignment)
- Check browser console for absence of Quill errors
Files Modified
frontend/src/components/common/CustomRichEditor.tsx
Related
- React Quill: https://github.com/zenoamaro/react-quill
- Quill.js: https://quilljs.com/