DEV Community

Cover image for Mastering the Art of Dynamic Content: A Guide to Harnessing DraftJS in React for Seamless Post Creation and Server Integration
AGBOOLA JOEL OLUWAFISAYO
AGBOOLA JOEL OLUWAFISAYO

Posted on

Mastering the Art of Dynamic Content: A Guide to Harnessing DraftJS in React for Seamless Post Creation and Server Integration

WHY DRAFTJS :
DraftJS is useful for effortless rich text editing, seamless integration with React, predictable state management, and editor customization with ease.
It also helps elevate your projects with a powerful, flexible, and developer-friendly solution.

INSTALLING RELEVANT DEPENDENCIES IN REACT:

Ensure you have npm installed. Open your terminal and run

npm install axios
npm install draft-js react-draft-wysiwyg

These are the main packages required for draftjs integration

Create editor component with draftjs

import React from "react";
import { EditorState } from "draft-js";
import { Editor } from "react-draft-wysiwyg";

const EditorComponent = ({ editorState, setEditorState }) => {
  const handleEditorChange = (newEditorState) => {
    // Ensure newEditorState is an instance of EditorState
    const updatedEditorState =
      newEditorState instanceof EditorState
        ? newEditorState
        : EditorState.createEmpty(); // You might want to adjust this based on your application logic
    setEditorState(updatedEditorState);
  };
  return (
    <>
      <Editor
        editorState={editorState}
        onEditorStateChange={handleEditorChange}  //handles editor states change when in use
        toolbarClassName="toolbar-class"
        editorClassName="editor-class"
        wrapperClassName="wrapper-class"
      />
    </>
  );
};

export default EditorComponent;

Enter fullscreen mode Exit fullscreen mode

Make use of the editor component in a post component that sends data to the server

import React, { useState } from "react";
import { EditorState, convertToRaw } from "draft-js";
import EditorComponent from "./EditorComponent";
import axios from "axios";

const PostToServer = () => {
  const [editorState, setEditorState] = useState(() =>
    EditorState.createEmpty()
  );
  //pass the state into the editor component to track changes in the editor
  const editorData = new FormData();

  const handlePostSubmit = async (e) => {
    e.preventDefault();
    const content = JSON.stringify(
      convertToRaw(editorState.getCurrentContent())
    );

    editorData.append("editorData", content);

    try {
      // this where we make use of axios
      const response = await axios.post(
        "http://localhost:8080/post/create-post", // url for server/backend which has a field called editor data
        editorData,
        {
          headers: {
            "Content-Type": "multipart/form-data",
            // Add any additional headers as needed (e.g., authorization headers)
          },
        }
      );
      console.log(response.data.editorData);
    } catch (error) {
      console.error(error.message);
    }
  };
  return (
    <form onSubmit={handlePostSubmit}>
      <EditorComponent
        editorState={editorState}
        setEditorState={setEditorState}
      />
      <button type="submit">Button for storing post value on backend</button>
    </form>
  );
};

export default PostToServer;

Enter fullscreen mode Exit fullscreen mode

Editor data being sent to server/backend should appear like this


content: {"blocks":
[
{"key":"4rh99","text":"It's very gray today. I ate cornflakes ","type":"unstyled","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":{}},
{"key":"fdh6","text":"honey","type":"unordered-list-item","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":{}},{"key":"13aee","text":"a banana","type":"unordered-list-item","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":{}},{"key":"bb1p5","text":"and peanutbutter ","type":"unordered-list-item","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":{}},{"key":"8j2ad","text":"for breakfast. ","type":"unstyled","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":{}},{"key":"fjio6","text":"","type":"unstyled","depth":0,"inlineStyleRanges":[],"entityRanges":[],"data":{}},{"key":"eblll","text":"Valentine's day is this weekend. ","type":"unstyled","depth":0,"inlineStyleRanges":[{"offset":0,"length":16,"style":"BOLD"}],"entityRanges":[],"data":{}}],"entityMap":{}}

finally we create another component to get the data that has been stored on the server

import { useEffect, useState } from "react";
import axios from "axios";
import { Editor, EditorState, convertFromRaw } from "draft-js";

const GetData = () => {
  const [apiData, setApiData] = useState([]);
  //   state for editor data gotten from server
  useEffect(() => {
    const fetchData = async () => {
      try {
        const response = await axios.get("http://localhost:8080/post/get-post");
        setApiData(response.data.editorData);
        console.log("editor api Response:", response.data.editorData);
      } catch (error) {
        console.error(error.message);
      }
    };
    fetchData();
  }, []);

  return (
    <>
      {apiData.map((data) => {
        const contentState = convertFromRaw(JSON.parse(data.body));
        const editorState = EditorState.createWithContent(contentState);
        return (
          <div>
            <Editor editorState={editorState} readOnly={true} />
            {/* the readOnly value enable editor reads the data gotten from the server and display it again through draftjs */}
          </div>
        );
      })}
    </>
  );
};

export default GetData;

Enter fullscreen mode Exit fullscreen mode

Summary

POST
Get current content from the editor state using

JSON.stringify(convertToRaw(editorState.getCurrentContent()))
Enter fullscreen mode Exit fullscreen mode

which then convert the current state to a string .

GET
Display the data in a Draft.js Editor set to readOnly.
Fetch the post from the server and then convert it to readable content with this.

const contentState = convertFromRaw(JSON.parse(data.body));
    const editorState = EditorState.createWithContent(contentState);
Enter fullscreen mode Exit fullscreen mode

Show it in an Editor like so:

<Editor editorState={editorState} readOnly={true}
Enter fullscreen mode Exit fullscreen mode

Drop a like and share if you found this helpful.⚙👩‍💻

Top comments (0)