Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom Editing Area losing focus in React 16 #309

Closed
ahutch1211 opened this issue Dec 27, 2017 · 60 comments
Closed

Custom Editing Area losing focus in React 16 #309

ahutch1211 opened this issue Dec 27, 2017 · 60 comments
Labels
follow up The issue is likely improved by recent developments. Follow up with poster to make sure good first issue

Comments

@ahutch1211
Copy link

ahutch1211 commented Dec 27, 2017

I have noticed an issue after upgrading to React 16. I have a React Quill component that is being managed by the parent.

class Editor extends Component {
  constructor(props) {
    super(props);

    this.handleOnChange = this.handleOnChange.bind(this);
    this.handleOnBlur = this.handleOnBlur.bind(this);
  }

  handleOnChange(html, delta, source) {
    const { onChange } = this.props;

    if (source === 'user') {
      onChange(html);
    }
  }

  handleOnBlur(range, source, quill) {
    const { onBlur } = this.props;
    
    if (source === 'user') {
      onBlur(quill.getHTML());
    }
  }

  render() {
    const { value } = this.props;
    
    return (
      <ReactQuill
        value={value}
        modules={modules}
        onChange={this.handleOnChange}
        onBlur={this.handleOnBlur}
        theme="snow">
        <Container />
       </ReactQuill>
    );
  }
}

class Parent extends Component {
  constructor(props) {
    super(props);
    
    this.state = {
      value: '<h1>Testing Quill</h1><strong>Custom Editing Area</strong>'
    };
    
    this.handleOnChange = this.handleOnChange.bind(this);
    this.handleOnBlur = this.handleOnBlur.bind(this);
  }
  
  handleOnChange(value) {
    this.setState({ value });
  }
  
  handleOnBlur(value) {
    this.setState({ value });
  }
  
  render() {
    return (
      <Editor
	value={this.state.value}
	onChange={this.handleOnChange}
	onBlur={this.handleOnBlur}
      />
    );
  }
}

This code appears to be working in React 15. However, in React 16, it will lose focus and throw this console error after an onChange event; The given range isn't in document. I believe this is due to the selection not being updated correctly. If you take out the custom editing area, this code will work inside React 16.

I have attached an example in Codepen, in here you can set the dependencies for React 15 vs React 16 to notice the error.

In the meantime, we have removed the custom editing area and wrapped React Quill with a styled component and an '.ql-editor' selector to add a custom style to the editing area.

Thanks for your time!

@rsolci
Copy link

rsolci commented Feb 1, 2018

I have this issue as well. Tried a lot of things before finding this. Removing Custom Editing Area stopped the error.
Weird thing: On Firefox 58 i got the same lose focus behaviour but without the console error.

@jonathanlaf
Copy link

jonathanlaf commented Mar 16, 2018

Any news on that problem ? I have it too... I found that the key of the div is updated each time you submit a statechange

@alexkrolick
Copy link
Collaborator

This may be due to a change in the lifecycle of React components in React 16. One of these?

  • When replacing <A /> with <B />, B.componentWillMount now always happens before A.componentWillUnmount. Previously, A.componentWillUnmount could fire first in some cases.
  • Previously, changing the ref to a component would always detach the ref before that component's render is called. Now, we change the ref later, when applying the changes to the DOM.
  • It is not safe to re-render into a container that was modified by something other than React. This worked previously in some cases but was never supported. We now emit a warning in this case. Instead you should clean up your component trees using ReactDOM.unmountComponentAtNode. See this example.

@nucab
Copy link

nucab commented Jun 4, 2018

Try to set an id for parent and child.

static getDerivedStateFromProps(props, state) {
  if (props.id !== state.id) {
    return {
      id: props.id,
      editorHtml: props.defaultValue,
    };
  }
  return null;
}

@rsolci
Copy link

rsolci commented Jun 20, 2018

Like this: https://codesandbox.io/s/k3jqjr78pr ?
The component still loses its focus after each key press.
Tested on Chrome and Firefox, both on last version, Ubuntu Linux

@Bertg
Copy link

Bertg commented Jul 18, 2018

+1 Interested to see this fixed

@keya129
Copy link

keya129 commented Sep 13, 2018

+1 Same Issue

@SerhiiKozachenko
Copy link

Noticed that error occurs only in dev mode, after I build assets with webpack it doesn't reproduce anymore.

@erick2014
Copy link

Hey guys, can I work in this issue?

@alexkrolick
Copy link
Collaborator

Yes, please do! @erick2014

@Tailball
Copy link

Tailball commented Nov 12, 2018

Is there already a solution for this? Or a viable workaround?

I have migrated from React 15 to React 16 this weekend.
A perfectly working Quill now is very buggy...

When I type in my input field, many times (it seems to be working when typing REALLY slow) the cursor jumps back to position 0 (the front).
And I seem to be getting an error on Chrome when that happens: 'Given range isn't in document'.
The error only shows up on Chrome, but the cursor-jumping appears on all major browsers.

I would prefer not rewriting any Quill implementation code, since it was working smooth as butter on React15 and I am hesitant to rewrite/refactor and introduce bugs in existing production code...

Edit: currently working around this issue by not using children components in the QuillEditor ReactQuill component.

@nirupama7
Copy link

nirupama7 commented Nov 15, 2018

+1 same issue.

@erick2014
Copy link

erick2014 commented Nov 19, 2018

huy guys, I'm checking this issue to see what's the problem

@erick2014
Copy link

@alexkrolick is there any contribution guide to follow? I have no idea how to debug this

@alexkrolick
Copy link
Collaborator

You can step through the editor in the example with Chrome devtools

@ddzy
Copy link

ddzy commented Nov 20, 2018

+1 same issue.

+2 same issue too

@ddzy
Copy link

ddzy commented Nov 20, 2018

After insert a picture, the following error occurs when I enter something else↓↓↓
issue

@erick2014
Copy link

@alexkrolick do you mean checking the demo in the repo?

@alexkrolick
Copy link
Collaborator

Yes, clone locally and run the demo build in package.json, then you can debug a live editor

@3lang3
Copy link

3lang3 commented Dec 20, 2018

same issue

@david0723
Copy link

Same issue

@Angrigo
Copy link

Angrigo commented Jan 27, 2019

same issue

@sammylupt
Copy link

Are there any known workarounds to this bug?

@nirupama7
Copy link

I ended up using draft js after a lot of research on this.

@FoxyWolfy
Copy link

FoxyWolfy commented Mar 8, 2019

Same issue....

Quill is brought to it's knees when using: "div className="my-editing-area"

Warning: isMounted(...) is deprecated in plain JavaScript React classes. Instead, make sure to clean up subscriptions and pending requests in componentWillUnmount to prevent memory leaks.
react.development.js:129
Warning: replaceState(...) is deprecated in plain JavaScript React classes. Refactor your code to use setState instead (see facebook/react#3236).
react.development.js:129
addRange(): The given range isn't in document. quill.js:3145

@MateuszKrazek
Copy link

MateuszKrazek commented Mar 14, 2019

My experience with Quill - Problems + solutions:

My environemt: imagine a left panel with items from 1 to 10, and the main container with 6 properties to be filled in by User with React Quill text editor, so 60 properties in total.
Each item is clickable, so after clicking item1, the 6 text editors gets shown (either empty or with previously saved data), when clicking item2, next 6 text editors gets shown either empty or with previously saved data), and so on....

Problem 1:
Now, it was like, when I typed 1111 into the item1 text editor field and then navigated to item2, the value for the latter was still 1111 - so it was showing the value for the item that was firstly clicked. Whichever item was clicked next, got the same value (of item1).

Solution:
in the text-editor.tsx, so the place where we instatiante the ReactQuill, we were setting its value by defaultValue property, and not by value - which means, that this component
was not managed by React, which means, that it was not responding (refreshing) when the props or state was change. So I changed that to value, which cause the next problem.

Problem 2:
it was like, when I typed first character, the Quill was totally losing focus and throwing "addRange(): The given range isn't in document." error

Solution:
It turned out, that the Quill was not initialized with the proper value - so the empty Delta format. What we were using was {} but what is declared as empty Delta looks like this { ops: [] }
the code snippet:
if( !content || content.length === 0 || ( content.constructor === Object && Object.entries(content).length === 0 )) {
content = { ops: [] }
}

and that this content goes to ReactQuill value property, so ..., value={content} ...

Problem 3:
This was a tricky one, but we have those 6 text editors per tiem, right. It was working like the first was ok, the second losed focus and "addRange(): The given range isn't in document." error, the third ok, the forth lost focus "addRange(): The given range isn't in document." error, and so on.

Solution:
It turned out that we had two instances of the Quill defined, but that is due to the specification of our environment. We have a common repository with shared custom components, like this ReactQuill wrapper, and that the sub-repositories that uses this common one together with its own. Meaning, the first one was defined in the sub-repository's package.json and the second one was in this common ones package.json. I removed the one from sub-repository and left only the one defined in common, so de facto, the one that have this wrapper component.

Problem 4:
We started using Quill with the string data format, but at some point last year we decided to abandon this format, because it was causing some strange and hard to solve problems with formatting (e.g. it was adding extra lines when User navigate to a view with Quill, but did nothing, etc), so we decided to change it to Delta format - without those problems. We could do it back then because the Quill is supporting both the formats by default. We did not need any data migration, because it was just working, the problems started to occure when we ofc upgraded to React 16+. This means, that we had an "old" data of type string, and the "new" ones with delta format. Now, inside the onQuillChange in text-editor-wrapper component we have sth like this:

onQuillChange(textHTML: string, delta: Delta, source: string, editor: Quill){
        let content: any = editor.getContents();  <---- this returns Delta to Parent component and handles it there 
		this.props.onChange(textHTML, content)

which means, that on every change it gets the content (which is the Delta) and returns it in callback together with textHTML.
So it was like this: when the initial format was string, the OnChange changes that to Delta and returned to be saved as Delta - it turned out that Quill does not "like" this on-the-fly change and looses the connection to its instance, hence the focus got lost and "addRange(): The given range isn't in document." error

Solution:
What I did is that inside the parent component, so the one that executes the callback, I modified the handler function to look more-less like this:

	handleTextChange = (html: String, delta: Delta) => {      
		if(typeof this.state.xxxxxxx.myPropertyUsingQuill === "string") {
            this.xxxxxAttributeChanged(html, 'myPropertyUsingQuill');
        } else {
            this.xxxxxAttributeChanged(delta, 'myPropertyUsingQuill');
        };
	}

so whenever it starts working on a string data initially, it continues on a string, and when the initial value is Delta, it is working on Delta.

Problem 5:
So we have this modified handler. Now, what it turned out, is that when You started working on item1, which is the Delta format, it works fine, than You navigate to next item, item2, which has a string format of the value saved inside, boom, the focus is lost and "addRange(): The given range isn't in document." error - the focus was also lost the other way arround with data formats mentioned.

Solution:
So it turned out, that once the React Quill is mounted, it is still the same instance when navigating between different items. The values are just passed in inside the props. So in this case, it instatiated itself with Delta, but after clicking on item2, it did not reinstantiated itself with the string format (so still waiting to use Delta, but got string), hence the problem, focus lost, "addRange(): The given range isn't in document." error. I solved that by adding the key property inside the declaration, so sth like this:

<MyTextEditor id="xxxxx_myPropertyUsingQuill" 
                                key={xxxxx.uniqueId}

this key property makes the MyTextEditor reinstantiate itself whenever the key is different.

Problem 6:
It was actually a corner case, because what we've found is that, when the value provided to Quill is an empty string, it fails because it starts as a string, but than the logic inside text-editor-component transformes it to Delta format and uses it as a Delta, so there is a problem. The original was string, but returned was Delta, so the focus is lost, "addRange(): The given range isn't in document." error.

Soliution:
I extended the callback handler in the parent component to look like this:

	handleTextChange = (html: String, delta: Delta) => {
		if(typeof this.state.xxxxxxx.myPropertyUsingQuill === "string"  && (this.state.xxxxxxx.myPropertyUsingQuill as string).length > 0) {
            this.xxxxxAttributeChanged(html, 'myPropertyUsingQuill');
        } else {
            this.xxxxxAttributeChanged(delta, 'myPropertyUsingQuill');
        };	
    }

This means, that for initial values provided to Quill that are of type string, but have something inside, it will work in the string mode,
and for empty formats and Delta-type values provided to Quill, it will work in Delta mode.

Hope it will help some of You guys help Your issues.

@dharnen
Copy link

dharnen commented Mar 19, 2019

@MateuszKrazek
Thank you very much for the in depth explanation of each of the problems you faced and the solution corresponding to each. I actually have a similar setup with a side panel of items and a main container for each with multiple quill fields for each item. It sounds like each one of you quill components is using a passed value (via props) to initially show previously saved data if there is any. How were you able to set up your component to allow for the changed values in the editor to be "lifted up" to the parent?

Like a lot of other people who are seeing the "addRange(): The given range isn't in document" error, every time I try to call a function passed through props in the onChange() function I am faced with the addRange() error. If the component is uncontrolled (values are stored and updated withing the state and do not come from props) things work fine. Just curious if you found a way around this.

Thanks!

@renaudtertrais
Copy link

renaudtertrais commented May 2, 2019

I had, again, the same issue and this time, it was caused by changing the value in the handler (removing extra <p><br></p>). I solved it by creating a local state updated when value changed:

function MyEditor({ value, onChange }){
 const [state, setState] = useState({ value });

  useEffect(() => {
    if (state.value !== value) setState({ value });
  }, [value]);

  return (
     <Editor
        value={state.rawValue || state.value || ''}
        onChange={rawValue => {
          const cleanedValue = rawValue.replace(/<p><br><\/p>/g, '');
          setState({ rawValue, value: cleanedValue });
          onChange(cleanedValue);
        }}
    />
  );
}

@semoal
Copy link

semoal commented May 5, 2019

I had, again, the same issue and this time, it was caused by changing the value in the handler (removing extra <p><br></p>). I solved it by creating a local state updated when value changed:

function MyEditor({ value, onChange }){
 const [state, setState] = useState({ value });

  useEffect(() => {
    if (state.value !== value) setState({ value });
  }, [value]);

  return (
     <Editor
        value={state.rawValue || state.value || ''}
        onChange={rawValue => {
          const cleanedValue = rawValue.replace(/<p><br><\/p>/g, '');
          setState({ rawValue, value: cleanedValue });
          onChange(cleanedValue);
        }}
    />
  );
}

In my project with your code, the issue persist mate.

@semoal
Copy link

semoal commented May 7, 2019

@renaudtertrais in your example you're not using a custom editing area, try this example and you will see this bug it's still open...

function MyEditor({ value, onChange }){
 const [state, setState] = useState({ value });

  useEffect(() => {
    if (state.value !== value) setState({ value });
  }, [value]);

  return (
     <Editor
        value={state.rawValue || state.value || ''}
        onChange={rawValue => {
          const cleanedValue = rawValue.replace(/<p><br><\/p>/g, '');
          setState({ rawValue, value: cleanedValue });
          onChange(cleanedValue);
        }}
    >
          <div id="target"></div>
    </Editor>
  );
}

@robphoenix
Copy link

I had this issue and got it working by using defaultValue instead of value

const MyEditor = () => {
  const [editorContent, setEditorContent] = React.useState(``)

  return (
    <ReactQuill
      defaultValue={editorState}
      onChange={(value) => setEditorState(value)}
     />
  )
}

@MateuszKrazek
Copy link

@robphoenix check out this post #309 (comment) and read the Problem #1.

@robphoenix
Copy link

@MateuszKrazek ok, sorry you still have issues, this is just what fixed it for me 🤷‍♀️

@timtamimi
Copy link

timtamimi commented Jan 9, 2020

FWIW I encountered the same issue when I included Quill in a functional component, which was then being rendered as a child of another functional component. The issue seemed to be present when I used a combination of onChange = evt => {} and modules={whatever}

The "solution" (read: workaround) was to use a class component instead for the Quill editor.

Below is my new (working) Quill component:

import React, { Component } from "react";
import ReactQuill from "react-quill";
import 'react-quill/dist/quill.snow.css';

export default class MessageComposer extends Component {
    constructor(props) {
        super(props);
        this.state = {
            text: null
        };
    }

    handleSubmit = () => {
        this.props.submissionHandler(this.state.text);
        this.setState({
            text: null
        })
    }

    handleChange = (content, delta, source, editor) => {
       this.setState({
           text: content
       })
    };

    render() {
        return (
            <ReactQuill
                theme="snow"
                modules={{
                    keyboard: {
                        bindings: {
                            enter: {
                                key: 13,
                                handler: this.handleSubmit
                            }
                        }
                    }
                }
                }
                value={this.state.text}
                onChange={this.handleChange}
            />
        );
    }
}

Hope it helps.

@chrisnorwood
Copy link

@robphoenix solution worked great.

Side note: if one is fetching their defaultValue asynchronously, make sure it's received and set before rendering the quill component — and this works great!

@zenoamaro
Copy link
Owner

Hello all!

Most of the issues in this thread, with related issues related to state changes and focus management, have been a core topic in the latest beta versions. The update detection and regeneration mechanisms have been reworked, and everything should now work properly when using value, modules, deltas, parent components.

I have updated the Codepen on the original post to the latest beta, and I don't seem to be getting any ill effects anymore: https://codepen.io/zenojevski/pen/LYpbyVP?editors=0010

Can you verify? npm install react-quill@beta should do the trick


Note: white-space issues when using strings are acknowledged, even though there is no solution yet. They might be improved by using the matchVisual clipboard setting, or deltas, as has been suggested at various points in the thread. It will be addressed in the short term, at the very least via an official recommendation.

@zenoamaro zenoamaro added the follow up The issue is likely improved by recent developments. Follow up with poster to make sure label Apr 21, 2020
@alexkrolick
Copy link
Collaborator

@zenoamaro apparently matchVisual will be removed in Quill v2. We are on the stable version (1.3), but it's something to be aware of.

@marinona
Copy link

marinona commented Jul 7, 2020

Prevent creating modules object each render.
I used useMemo hook and it solved the problem

@murillo94
Copy link

It's seems that each re-render the modules object are recreating. To prevent this behaviour, i used useMemo.

const modules = React.useMemo(
   () => ({
     toolbar: { ... }
   }),
   [<any-value-to-compare-or-none>]
)

@Jezternz
Copy link

Jezternz commented Aug 2, 2020

thanks @marinona / @murillo94! Works perfectly now :)

@moojing
Copy link

moojing commented Aug 8, 2020

+1 ,the way of @marinona and @murillo94 works !! Thx, you save my day.

@evanjmg
Copy link

evanjmg commented Aug 10, 2020

You must use @murillo94 and/or @timtamimi's solution to work, every function and object has to be memoized as a prop or it will clear the focus - so best to use a class

@mmstarz
Copy link

mmstarz commented Sep 16, 2020

i've got similar issue when used react-quill.

warning addRange(): The given range isn't in document.
and quill field loose focus.

i used react functional component with:

// two states

const [formStatus, setFormStatus] = useState(false);
const [formSchema, setFormSchema] = useState({ ...postForm });

// standart form handlers

const cleanFormState = () => {...}
const formValidation = (schema) => {
  ...
 setFormStatus(valid);
}
const handleChange = (e) => {...}
const handleTouch = (e) => {...}
const handleBlur = (e) => {...}
const handleSubmit = (e) => {...}

and a form as a return

<div>
  <form>
     {/* that includes **several input fields** and **ReactQuill** component as a main content field. */}
  </form>
</div>

okay. now what was the problem?

The issue uccurs while handling change value event.

BEFORE FIX

const handleChange = (e) => {		
	let updatedSchema = {
		...
	};			
	
	formValidation(updatedSchema);
        setFormSchema(updatedSchema);
};

AFTER FIX

const handleChange = (e) => {		
	let updatedSchema = {
		...
	};
	**// !!! important to save changed schema state first**		
	setFormSchema(updatedSchema);
	formValidation(updatedSchema);
};

thx. and hope it helps someone.

@sanskarpustack
Copy link

@timtamimi converting to class component did not work

@theindianappguy
Copy link

thanks @marinona and @murillo94 it worked, i made a simple mistake of removing bolded completely

const modules = React.useMemo(
() => ({
toolbar: { ... }
}),
[]
)

@Thyrannoizer
Copy link

Thyrannoizer commented Oct 8, 2020

either useMemo neither useEffect worked for me on "react-quill": "^1.3.5", "react": "^16.13.1"

const modules = useMemo( () => ({ toolbar: [[{ header: [1, 2, false] }], ['bold', 'italic', 'underline']], }), [] );

return ( <ReactQuill modules={modules} theme="snow" value={value} onChange={value => setValue(value)}> <div style={{ height: 200 }} /> </ReactQuill> );

@marinona
Copy link

marinona commented Oct 8, 2020

either useMemo neither useEffect worked for me on "react-quill": "^1.3.5", "react": "^16.13.1"

const modules = useMemo( () => ({ toolbar: [[{ header: [1, 2, false] }], ['bold', 'italic', 'underline']], }), [] );

return ( <ReactQuill modules={modules} theme="snow" value={value} onChange={value => setValue(value)}> <div style={{ height: 200 }} /> </ReactQuill> );

@Thyrannoizer are you defining "modules" inside the component's definition? It should be outside and it might be the problem.
It should be like this:

const modules = ....

const MyComponent = () => {
return( <ReactQuill modules = {modules} ......./>
}

Hope it helps!

@MiguelAlvarez129
Copy link

MiguelAlvarez129 commented Oct 11, 2020

I've been having the same problem as @Thyrannoizer , doesn't matter whether i define modules inside an useMemo or outside the component's definition, my custom editing area still loses focus after typying and on the console appears a warning message quill.js:3195 addRange(): The given range isn't in document., i'm using "react": "^16.13.1" and "react-quill": "^1.3.5".
Here's my code, my TextArea component is just a custom div styled component.

import React, { useEffect, useMemo, useState } from "react";
import ReactQuill from 'react-quill';
import 'react-quill/dist/quill.snow.css'; 

import {TextArea} from '../shared/styles'

    const modules = {
    toolbar: [ ['bold', 'italic', 'underline']]
    }

const Editor = (props) =>{
    const [value, setValue] = useState('')
    const onChange = (e) =>{
        
        setValue(e)
    }

   return (
    <ReactQuill 
        modules={modules}
        theme='snow'
        onChange={onChange}
        value={value}
        
>
    <TextArea/>
</ReactQuill>
 

   )
}

@marinona
Copy link

I've been having the same problem as @Thyrannoizer , doesn't matter whether i define modules inside an useMemo or outside the component's definition, my custom editing area still loses focus after typying and on the console appears a warning message quill.js:3195 addRange(): The given range isn't in document., i'm using "react": "^16.13.1" and "react-quill": "^1.3.5".
Here's my code, my TextArea component is just a custom div styled component.

import React, { useEffect, useMemo, useState } from "react";
import ReactQuill from 'react-quill';
import 'react-quill/dist/quill.snow.css'; 

import {TextArea} from '../shared/styles'

    const modules = {
    toolbar: [ ['bold', 'italic', 'underline']]
    }

const Editor = (props) =>{
    const [value, setValue] = useState('')
    const onChange = (e) =>{
        
        setValue(e)
    }

   return (
    <ReactQuill 
        modules={modules}
        theme='snow'
        onChange={onChange}
        value={value}
        
>
    <TextArea/>
</ReactQuill>
 

   )
}

@MiguelAlvarez129 I think your problem is because you are trying to use the Quill Editor as a controlled component.
In the documentation they explain how "value" and "onChange" work in the Quill component, i hope it helps: https://github.com/zenoamaro/react-quill#usage
I've tried your example and it works as a uncontrolled component (removing "value" and "onChange" props).

@Ashesashu860
Copy link

THIS SOLUTION WORKED FOR ME IN REACT FUNCTIONAL COMPONENT AS WELL !!

Don't use ReactQuill as a controlled component. That means, remove "value" prop from ReactQuill because you dont need to set the value in ReactQuill explicitly because it handles that on its own. You can keep "onChange" function to get the updated value on every change. Now, just have a variable(not a state variable) and set that variable on every change. Then access that very variable when you want to get the whole content.

let data = null; const onChange = (content, delta, source, editor) => { data = content; };

<ReactQuill theme="snow" modules={modules} onChange={onChange} formats={formats} placeholder="Enter your thoughts..." > <div className="my-editing-area" /> </ReactQuill>

Hope this works for you too. !!

@Jezternz
Copy link

THIS SOLUTION WORKED FOR ME IN REACT FUNCTIONAL COMPONENT AS WELL !!

Don't use ReactQuill as a controlled component. That means, remove "value" prop from ReactQuill because you dont need to set the value in ReactQuill explicitly because it handles that on its own. You can keep "onChange" function to get the updated value on every change. Now, just have a variable(not a state variable) and set that variable on every change. Then access that very variable when you want to get the whole content.

let data = null; const onChange = (content, delta, source, editor) => { data = content; };

<ReactQuill theme="snow" modules={modules} onChange={onChange} formats={formats} placeholder="Enter your thoughts..." > <div className="my-editing-area" /> </ReactQuill>

Hope this works for you too. !!

That will work for simple cases but sometimes a controlled component is desirable. Eg if you want to modify the value in another component eg a "clear value" button, or if you want to take in asynchronous updates from the backend.

@qasimmehdi
Copy link

I had the same issue using quill-mention, the editor was loosing the focus everytime a key was pressed. The issue was that I was recreating modules at each render. Caching it fixed the problem. More details here: quilljs/quill#1940 (comment)

When I created a keyboard binding to disable delete key(key code 46) I was also facing issue with focus. I fixed the issue by putting my bindings outside of component.

Before:
keyboard:{
bindings: {//binding here}
}

After:
const bindings = {//binding here}//outside component

keyboard:{
bindings: bindings
}

@Eduardo-Mercado
Copy link

thanks @marinona and @murillo94 it worked, i made a simple mistake of removing bolded completely

const modules = React.useMemo( () => ({ toolbar: { ... } }), [****] )

Thank mate, that work well

@Prabhakar-Poudel
Copy link

@alexkrolick why has this issue been closed? I see a couple of workarounds but the bug is still there.
It would be nice to close it once the problem itself is solved by the lib 🤔

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
follow up The issue is likely improved by recent developments. Follow up with poster to make sure good first issue
Projects
None yet
Development

No branches or pull requests