When using functional component with react hook, the useRef hook breaks the rendering when changing state.
I have noticed that by adding a ref to ReactQuill, in order to access it through a custom handles, crashes the rendering. Without a ref, the component works fine but I can't manipulate it through a handler, also, without the value={value} property, it works fine, but I can't manage the value state.
I've made a pen as example, in my computer, both in the project I've been working and in an isolated project, when typing in the editor, it goes blank, it's just dropped from DOM. When using in codepen, it behaves oddly when typing and loses focus each change.
This is fixed in v2.0.0-beta.2! You can quickly verify the fix by updating your Codepen to use https://unpkg.com/react-quill@beta/dist/react-quill.js. Can you confirm this solves your issues in your main project as well?
It worked! But I came across another error :/ when I trigger the custom handler, I get a "Maximum update depth exceeded" error.
It happens when I choose an style "uppercase, lowercase, capitalize" from the custom "Style" dropdown. It then sets it in like so: node.setAttribute('style', `text-transform: ${value};`);, with value being the three styles mentioned above.
I noticed removing the section
static formats(domNode) {
return domNode.getAttribute('style') || true;
}
solves the problem, but then the style is not set, so I suppose the error is triggered in this section.
You can check it in the same codepen. Select a part of the text and choose a style.

The same error happened in my main project, but the first one is fixed.
I also noticed a long delay after each key is pressed and it warns "addRange(): The given range isn't in document."
In v1.3.5, can't support custom upload image, when I update to v2.0.0-beta.2, It works, But now can't input chinese when I config image handler, It's ok close it.
const imageHandle = () => {
const editor = quillRef.current.getEditor()
const input = document.createElement('input')
input.setAttribute('type', 'file')
input.setAttribute('accept', 'image/*')
// input.setAttribute('multiple', 'multiple')
input.click()
input.onchange = async () => {
const files = input.files
try {
const reqData = await getData()
const list = await Promise.all(
Array.from(files, file =>
upload({
file,
action: '/upload/image',
filename: 'image',
data: {
token: generateToken(),
...reqData
},
headers: {}
})
)
)
console.log('list:', list)
console.log('getSelection:', editor.getSelection, editor.getSelection())
console.log('getLength:', editor.getLength, editor.getLength())
console.log('editor:', editor)
list.forEach(url => editor.insertEmbed(editor.getSelection(), 'image', url))
} catch (err) {
message.error('upload err, try again!')
}
}
}
const initModules = {
toolbar: {
container: toolbarOptions
// handlers: {
// image: imageHandle
// }
},
clipboard: {
// toggle to add extra line breaks when pasting HTML:
matchVisual: false
}
}
In
v1.3.5, can't support custom upload image, when I update tov2.0.0-beta.2, It works, But now can't input chinese when I config image handler, It's ok close it.const imageHandle = () => { const editor = quillRef.current.getEditor() const input = document.createElement('input') input.setAttribute('type', 'file') input.setAttribute('accept', 'image/*') // input.setAttribute('multiple', 'multiple') input.click() input.onchange = async () => { const files = input.files try { const reqData = await getData() const list = await Promise.all( Array.from(files, file => upload({ file, action: '/upload/image', filename: 'image', data: { token: generateToken(), ...reqData }, headers: {} }) ) ) console.log('list:', list) console.log('getSelection:', editor.getSelection, editor.getSelection()) console.log('getLength:', editor.getLength, editor.getLength()) console.log('editor:', editor) list.forEach(url => editor.insertEmbed(editor.getSelection(), 'image', url)) } catch (err) { message.error('upload err, try again!') } } } const initModules = { toolbar: { container: toolbarOptions // handlers: { // image: imageHandle // } }, clipboard: { // toggle to add extra line breaks when pasting HTML: matchVisual: false } }use useCallback
@leesama Can you elaborate? I'm facing the same issue.
You need to use useMemo or useCallback to memoize the plugin function and object creations, if these plugins are _defined inline_ in a function component. The ReactQuill wrapper will rebuild the editor if these values change identity.
You need to use useMemo or useCallback to memoize the plugin function and object creations, if these plugins are _defined inline_ in a function component. The ReactQuill wrapper will rebuild the editor if these values change identity.
I was having an issue, with a custom image handler, where any local state changes would make the quill disappear. Wrapping my custom handler in a useCallback worked for me.