zenoamaro / react-quill

A Quill component for React.
https://zenoamaro.github.io/react-quill
MIT License
6.69k stars 910 forks source link

React Quill removing all formatting and html tags from values when using used from a reopened modal #814

Open Johnrobmiller opened 2 years ago

Johnrobmiller commented 2 years ago

I am unable to provide code that replicates this, but here are the instructions:

Speculation about the cause: It might have something to do with some race condition when we dynamically import the ReactQuill input into the modal. However, this is just speculation.

Hacky workaround: if I have a "firstRender" state, set it to true initially, set it to false using useEffect(..., []), but then render null on the first render by checking if "firstRender" is true, then the bug will no longer occur.

keilestone commented 2 years ago

same :(

thuongbui1 commented 1 year ago

the same bug, The value auto remove some tags html.

jeremylaiyt commented 1 year ago

@Johnrobmiller thanks for providing this workaround.

Sateesh2 commented 1 year ago

This is for the people who did not have luck with delaying by one render as suggested. This issue might be happening due to the modal opening animation. If we set the rich text to quill editor before it appears on screen, it may calculate the new lines at the wrong time.

In my case, the modal is animating from zero size to full size, and I am setting the rich text at zero size. So I removed the animation and the problem was solved. If you don't want to remove the animation, listen to the animation ending then set the value to quill editor.

jjavierdguezas commented 1 year ago

Something similar to this happens to me using CRA and Ant Design in a Modal component: react-quill was removing tags from the initial value that I passed to it. The workaround proposed here worked well for me. thanks @Johnrobmiller

import { Modal, ModalProps} from 'antd';
import { FC, useEffect, useState } from 'react';
import ReactQuill, { ReactQuillProps } from 'react-quill';

const DescriptionModal: FC<
  Omit<ModalProps, 'onOk'> & {
    onOk: (html: string) => void;
    initialValue?: string;
  }
> = ({ onOk, initialValue='', ...modalProps }) => {

  const [isInitialRender, setIsInitialRender] = useState(true);

  const [html, setHtml] = useState<string>(initialValue || '');

  useEffect(() => setIsInitialRender(false), []);

  return (
    <Modal
      {...}
      {...modalProps}
      onOk={() => onOk(html)}
    >
      {!isInitialRender && (
        <>
          {...}
            <ReactQuill {...} value={html} onChange={(v) => setHtml(v)} />
          {...}
        </>
      )}
    </Modal>
  );
};

export default ServiceDescriptionModal;
McleanWorkshield commented 1 year ago

Not sure if this is the best answer, but I was not having luck by delaying the render.

I use the source argument, which is the string value "user" if the on change event comes from the user typing. This way I only execute the on change event as intended preventing the stripping of the html tags.

<ReactQuill
  // ... your props
  onChange={(value, _delta, source) => {
    if (source === "user") form.setFieldValue(field.name, value);
   }}
/>
vishwakarmanikhil commented 8 months ago

@jjavierdguezas Comment works for CRA and Ant Design in a Modal. I have debugged it, and I am not sure why it is like this when the component gets mounted and we are assigning some predefined HTML code to the Quill editor value the onChange function gets triggered automatically, but when the value reaches to first time onChange function it already has stripped some of the HTML tags from it. Below code I have added in my example from @jjavierdguezas code which works for me.

const DescriptionModal = (props) => {
const { html } = props; 

const [isInitialRender, setIsInitialRender] = useState(true);
const [emailBodyValue, setEmailBodyValue] = useState('');

 const setHtml = (content, delta, source, editor) => {
        if(source === "user") {
            setEmailBodyValue(editor.getHTML());
        }
    };

return (
    <Modal
{...modalProps}
    >
      {!isInitialRender && (
        <>
          {...}
            <ReactQuill {...} value={html} onChange={setHtml} />
          {...}
        </>
      )}
    </Modal>
  );
};

export default DescriptionModal;
etulikov commented 3 months ago
const [isInitialRender, setIsInitialRender] = useState(true);

Not sure this question still actual, but I found that for CRA and Ant Design in a Modal destroyOnClose={true} cause this issue.

99Arrzel commented 2 months ago

This bug is not fixed yet A coworker found it in an Ant Design Modal. @jjavierdguezas solution works, but it's unclean

vvenommm commented 1 month ago

i am using Ant Design and and next.js 14 and the bug is not fixed yet 😫😫