You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NextJS14中ReactQuill v2.0.0焦点跳失问题求助(DOMNodeInserted弃用)

ReactQuill 2.0.0在NextJS 14中焦点跳转+DOMNodeInserted弃用警告问题

问题描述

在NextJS 14应用中使用react-quill 2.0.0包,此前运行正常。近期撰写新文章时,输入框焦点会自动跳转到页面顶部,脱离<ReactQuill/>组件,同时控制台出现弃用警告:

[Deprecation] Listener added for a 'DOMNodeInserted' mutation event. Support for this event type has been removed, and this event will no longer be fired.

经排查,该问题源于ReactQuill 2.0.0使用了已被Chrome移除支持的DOMNodeInserted事件。

当前实现代码

"use client"

import React, { useState } from 'react';
import dynamic from 'next/dynamic';
import 'react-quill/dist/quill.snow.css';
import axios from 'axios';

const NewPostPage = () => {

    const [content, setContent] = useState<string>('');
    const ReactQuill = dynamic(() => import('react-quill'), { ssr: false });

    const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
    event.preventDefault();
    const formData = new FormData(event.currentTarget);

    const title = formData.get('title') as string;
    const author = formData.get('author') as string;

   try {
        const response = await axios.post('/api/posts/create', {
        title,
        author,
        content,
    });

        if (response.status === 200) {
            alert('Post created successfully!');
            window.location.href = '/';
        }
    } catch (error: any) {
        throw new Error('Error creating post:', error);
    }
};

return (
<>
    <div className="p-4">
        <h1 className="text-3xl font-bold mb-2">Creating New Blog Post</h1>
        <hr className="mb-6"/>
    </div>
    <form onSubmit={handleSubmit}>
        <div className="p-4">
        <label htmlFor="author" className="text-gray-200 font-bold pb-4">Blog Post Title</label>
        <br/><br/>
        <input type="text" name="title" id="title" placeholder="Blog Post Title" className="w-full mb-4 p-3 bg-black" autoFocus={true} required />
    </div>
    <div className="p-4">
        <label htmlFor="author" className="text-gray-200 font-bold pb-4">Author Name</label>
        <br/><br/>
        <input type="text" name="author" id="author" placeholder="Author Name" className="w-full mb-4 p-3 bg-black" required />
    </div>
    <div className="p-4">
        <label htmlFor="content" className="text-gray-200 font-bold">Blog Content</label>
        <br/><br/>
        <ReactQuill
          theme="snow"
          value={content}
          onChange={setContent}
          style={{ height: '33vh', marginBottom: '40px', color: 'white' }}
        />
    </div>
    <div className="p-4">
      <button type="submit" className="border border-white px-4 py-2 rounded-md hover:bg-slate-900">Create Post</button>
    </div>
  </form>
        </>
    );
};

export default NewPostPage;

解决方案

1. 优先升级ReactQuill到最新版本

ReactQuill 2.0.0之后的版本已经将DOMNodeInserted替换为现代浏览器支持的MutationObserver,彻底解决该问题。执行升级命令:

npm update react-quill
# 或使用yarn
yarn upgrade react-quill

2. 优化动态导入位置

当前代码将ReactQuill的动态导入放在组件内部,可能导致每次组件渲染时重新初始化,加剧焦点异常。将动态导入移至组件外部:

"use client"

import React, { useState } from 'react';
import dynamic from 'next/dynamic';
import 'react-quill/dist/quill.snow.css';
import axios from 'axios';

// 移至组件外部,确保只初始化一次
const ReactQuill = dynamic(() => import('react-quill'), { ssr: false });

const NewPostPage = () => {
    // 原有逻辑保持不变
};

export default NewPostPage;

3. 临时禁用旧事件监听(不推荐长期使用)

若暂时无法升级,可通过Quill的初始化钩子手动移除DOMNodeInserted事件监听:

<ReactQuill
  theme="snow"
  value={content}
  onChange={setContent}
  style={{ height: '33vh', marginBottom: '40px', color: 'white' }}
  modules={{
    // 保留原有工具栏配置
    toolbar: ['bold', 'italic', 'underline', 'link'],
    editor: {
      init: (quill) => {
        // 遍历编辑器相关元素,移除DOMNodeInserted监听
        const targetElements = [quill.root, ...Array.from(quill.root.querySelectorAll('*'))];
        targetElements.forEach(el => {
          const listeners = getEventListeners(el).DOMNodeInserted;
          if (listeners) {
            listeners.forEach(({ listener }) => {
              el.removeEventListener('DOMNodeInserted', listener);
            });
          }
        });
      }
    }
  }}
/>

注意:该方案依赖浏览器非标准的getEventListeners API,仅适合临时调试,生产环境请优先升级版本。

4. 排查NextJS Strict Mode影响

NextJS 14的Strict Mode会触发两次组件渲染,可能导致组件初始化异常。若问题仍存在,可暂时关闭Strict Mode(不推荐长期),或确保组件逻辑在Strict Mode下稳定运行。


内容的提问来源于stack exchange,提问作者Devon Kiss

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 18:30:19