I am trying to populate my editorJS component by fetching the document data from firebase firestore database.
I am using fetchContext function that runs on page load using useEffect, which runs setEditorData that gets passed down to Editor component.
- I am not sure if this is the best way to fetch the document field data; it works, but is there a cleaner way to do this?
- How can I populate the editor component with this data I retrieve from database? It doesn’t seem to populate correctly, it always shows blank screen although
console.log(editorData)in DraftPage.tsx is returning the correct data
Code:
DraftPage.tsx
const DraftPage = () => {
const router = useRouter();
const { id } = router.query;
const [editorData, setEditorData] = useState<OutputData>({} as OutputData);
const { data: session } = useSession();
const fetchContext = async () => {
if (session && session.user && session.user.id) {
const docRef = doc(db, "users", session?.user?.id!, "drafts", id);
const docSnap = await getDoc(docRef);
if (docSnap.exists()) {
setEditorData(docSnap.data().editorData);
console.log(editorData); // This is printing the correct data I want
} else {
console.log("No such document!");
}
}
};
useEffect(() => {
fetchContext();
}, [session]);
return (
<DraftPanel
session={session}
editorData={editorData}
setEditorData={setEditorData}
draftId={id}
/>
);
};
export default DraftPage;
DraftPanel.tsx
type DraftPanelProps = {
session: Session | null;
draftId: string | string[] | undefined;
editorData: OutputData;
setEditorData: Dispatch<SetStateAction<OutputData>>;
};
const EditorBlock = dynamic(() => import("../editor/Editor"), {
ssr: false,
});
const DraftPanel = ({
session,
draftId,
editorData,
setEditorData,
}: DraftPanelProps) => {
return (
<EditorBlock
data={editorData}
onChange={setEditorData}
holder="editorjs-container"
/>
);
};
export default DraftPanel;
../editor/Editor.tsx
import React, { memo, useEffect, useRef } from "react";
import EditorJS, { OutputData } from "@editorjs/editorjs";
type Props = {
data?: OutputData;
onChange(val: OutputData): void;
holder: string;
};
const EditorBlock = ({ data, onChange, holder }: Props) => {
const ref = useRef<EditorJS>();
// initialize editorjs
useEffect(() => {
// initialize editor if we don't have a reference
if (!ref.current) {
const editor = new EditorJS({
holder,
data,
minHeight: 30,
async onChange(api, event) {
const data = await api.saver.save();
onChange(data);
},
});
ref.current = editor;
}
return () => {
if (ref.current && ref.current.destroy) {
ref.current.destroy();
}
};
}, []);
return <div className="px-16 pt-8" id={holder} />;
};
export default memo(EditorBlock);
