React QuillEditor acts weird when typing

23 Views Asked by At

I'm trying to type in React Quill, but every time i type the text cursor begins on the left and then the text as shown in the gif below, and when i try to backspace it won't, i should select the whole text to delete or put the cursor on the beginning of text to delete the last letter, this is the code i'm using.

PostInfo.jsx:

import QuillEditor from "../../components/textEditor/QuillEditor";

export default function PostInfo() {
  const [content, setContent] = useState("");
  // Define a separate state for Quill editor content
  const [editorContent, setEditorContent] = useState("");

  useEffect(() => {
    const getPost = async () => {
      try {
        const res = await axios.get("/posts/byid/" + path);
        setPost(res.data);
        setContent(res.data.content);
        setEditorContent(res.data.content);
      } catch (err) {
      }
    };
    getPost();
  }, [path]);

  const handleUpdate = async () => {
    if (!title || !content || !photo) {
      return;
    } else
      try {
        await axios.put(`/posts/${post._id}`, {
          content: editorContent,
        });
      } catch (err) {
      }
  };
  
    const onEditorChange = (value) => {
    console.log("onEditorChange called");
    setEditorContent(value);
  };
  
  return (
  <div>
                {/* POST CONTENT CONTAINER */}
              <div className="PostInfoPagePostContentContainer">
                <h3>Post Content</h3>
                {postInfoPageUpdateMode ? (
                  <div className="PostInfoPagePostEditorBoxUpdateMode">
                    <QuillEditor
                      value={editorContent}
                      onEditorChange={(value) => {
                        onEditorChange(value);
                      }}
                    />
                  </div>
                ) : (
                  <div className="PostInfoPagePostContentBox">
                    <p>{parse(post.content)}</p>
                  </div>
                )}
              </div>
              {/* END OF POST CONTENT CONTAINER */}
  </div>
  
  )
}

code of QuillEditor.js:

import React from 'react';
import ReactQuill, { Quill } from 'react-quill';
import "react-quill/dist/quill.snow.css";
import ImageResize from "quill-image-resize-module-react";

const __ISMSIE__ = navigator.userAgent.match(/Trident/i) ? true : false;

var icons = Quill.import("ui/icons");
Quill.register("modules/imageResize", ImageResize);
icons["undo"] = `<svg viewbox="0 0 18 18">
    <polygon class="ql-fill ql-stroke" points="6 10 4 12 2 10 6 10"></polygon>
    <path class="ql-stroke" d="M8.09,13.91A4.6,4.6,0,0,0,9,14,5,5,0,1,0,4,9"></path>
  </svg>`;
icons["redo"] = `<svg viewbox="0 0 18 18">
    <polygon class="ql-fill ql-stroke" points="12 10 14 12 16 10 12 10"></polygon>
    <path class="ql-stroke" d="M9.91,13.91A4.6,4.6,0,0,1,9,14a5,5,0,1,1,5-5"></path>
  </svg>`;

class QuillEditor extends React.Component {
    bandId;
    placeholder;
    onEditorChange;
    _isMounted;
    defaultValue;
    

    constructor(props) {
        super(props);

        this.state = {
            editorHtml: __ISMSIE__ ? "<p>&nbsp;</p>" : "",
            files: [],
        };
        this.reactQuillRef = null;
    }

    componentDidMount() {
        this._isMounted = true;
    }

    componentWillUnmount() {
        this._isMounted = false;
    }

    handleChange = (html) => {
        console.log('html', html)
        this.setState({
            editorHtml: html
        }, () => {
            this.props.onEditorChange(this.state.editorHtml);
        });
    };

    undoHandler = () => {
        this.reactQuillRef.editor.history.undo("undo");
      };
    
    redoHandler = () => {
        this.reactQuillRef.editor.history.redo("redo");
      };

    render() {
        return (
            <div>
                <ReactQuill
                    style={{height: '500px', padding: '0px', width: '100%',  maxWidth: '1150px' }}
                    ref={(el) => { this.reactQuillRef = el }}
                    theme={'snow'}
                    onChange={this.handleChange}
                    modules={this.modules}
                    value={this.props.value || this.state.editorHtml}
                    placeholder={this.props.placeholder}
                    
                />
            </div>
        )
    }

I don't what is wrong with it, here is the problem i'm facing in a gif: enter image description here

1

There are 1 best solutions below

0
Mr. Terminix On

The main reason is that you are changing the state of the parent component after setting the state for the child component. Update the state at the same time and it will works:

 handleChange = (html) => {
    console.log("html", html);
    this.props.onEditorChange(html);
    this.setState({
        editorHtml: html,
    });
};

I suggest you to use functional components, not class components. Also, pass the initial value from the parent component as initial value for a useState and below for value of the ReactQuill always use the state of the children component.