I'm working on creating a text editor that handle image uploads, everything works fine but when it re renders it completely disappears
I tried using useMemo on modules and also add a unqiue key to but nothing seemed to work. if im removing the image handler from my modules then it stops disappearing.
Can anyone please guide, what the error is?
const uploadToCloudinary = async (file: File): Promise<string> => {
//code for uploading
return url;
};
export interface EditorProps {
description: string;
setDescription: (description: string) => void;
}
export default function QuillEditor({
description,
setDescription,
}: EditorProps) {
const [value, setValue] = useState<string>(description || "");
const [qid, setId] = useState<string>("");
const reactQuillRef = useRef<ReactQuill>(null);
const onChange = (content: string) => {
setValue(content);
console.log(content);
setDescription(content);
};
const imageHandler = useCallback(() => {
const input = document.createElement("input");
input.setAttribute("type", "file");
input.setAttribute("accept", "image/*");
input.click();
input.onchange = async () => {
if (input !== null && input.files !== null) {
const file = input.files[0];
const url = await uploadToCloudinary(file);
const quill = reactQuillRef.current;
if (quill) {
const range = quill.getEditorSelection();
range && quill.getEditor().insertEmbed(range.index, "image", url);
}
}
};
}, []);
const modules = {
toolbar: {
container: [
[{ header: [1, 2, 3, 4, 5, 6, false] }],
["bold", "italic", "underline", "strike", "blockquote"],
[{ list: "ordered" }, { list: "bullet" }],
["link", "image"],
["code-block"],
[
{
color: [
"#000000", ...
],
},
{
background: [
"#000000", ...
],
},
],
["clean"],
],
handlers: {
image: imageHandler,
},
},
clipboard: {
matchVisual: false,
},
};
return (
<ReactQuill
ref={reactQuillRef}
theme="snow"
placeholder="Start writing..."
modules={modules}
formats={[
"header", ...
]}
value={value}
onChange={onChange}
style={{ height: "350px", overflowY: "auto" }}
/>
);
}
The
modules
object is recreated/re-defined whenever the component rerenders. Just memoize the object withuseMemo
: