mirror of
https://github.com/Dvorinka/MyClubServer.git
synced 2026-06-04 18:52:56 +00:00
dev day #80
This commit is contained in:
@@ -0,0 +1,114 @@
|
||||
# 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
|
||||
1. **Unstable module configuration** - The `handleImageUpload` callback was included in `quillModules` dependencies, causing the modules object to recreate on every render
|
||||
2. **Missing initialization guards** - Code attempted to access Quill editor methods before the editor was fully initialized
|
||||
3. **Concurrent DOM mutations** - MutationObserver showed Quill was initializing while DOM was being modified
|
||||
|
||||
## Solution Applied
|
||||
|
||||
### 1. Stabilized Image Upload Handler
|
||||
**Before:**
|
||||
```typescript
|
||||
const handleImageUpload = useCallback(() => { ... }, []);
|
||||
|
||||
const quillModules = useMemo(() => ({
|
||||
toolbar: {
|
||||
handlers: {
|
||||
image: onImageUpload ? handleImageUpload : undefined,
|
||||
},
|
||||
},
|
||||
}), [toolbarConfig, onImageUpload, handleImageUpload]); // handleImageUpload caused recreation
|
||||
```
|
||||
|
||||
**After:**
|
||||
```typescript
|
||||
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:**
|
||||
```typescript
|
||||
const quill = quillRef.current?.getEditor();
|
||||
if (quill) {
|
||||
quill.focus();
|
||||
// ... operations
|
||||
}
|
||||
```
|
||||
|
||||
**After:**
|
||||
```typescript
|
||||
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
|
||||
```typescript
|
||||
<ReactQuill
|
||||
key={`quill-${readOnly ? 'readonly' : 'edit'}`}
|
||||
// ... other props
|
||||
/>
|
||||
```
|
||||
|
||||
This prevents unnecessary remounting while allowing controlled reinitialization when mode changes.
|
||||
|
||||
### 4. Protected Image Manipulation Effect
|
||||
```typescript
|
||||
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
|
||||
1. Create a new article in admin panel
|
||||
2. Click "Vložit obrázek" or use toolbar image button
|
||||
3. Select and crop an image
|
||||
4. Verify image inserts without errors
|
||||
5. Test image editing features (resize, filters, alignment)
|
||||
6. 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/
|
||||
Reference in New Issue
Block a user