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

React-Quill组件输入时消失问题求助

ReactQuill编辑器输入时消失的问题排查与修复

我开发了一个React应用,使用Quill编辑器创建帖子,但每当在任意输入字段(包括Quill编辑器本身)开始输入时,编辑器会完全消失。

问题截图

  • 输入前状态:输入前的状态
  • 输入后状态:开始输入后的状态

我的代码

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


const CreatePost = () => {

    const modules = {

        toolbar: [
            ['bold', 'italic', 'underline', 'strike'],          // toggled buttons
            ['blockquote', 'code-block'],
            [{ 'header': [1, 2, 3, 4, 5, 6, false] }],
            [{ 'list': 'ordered' }, { 'list': 'bullet' }],
            [{ 'script': 'sub' }, { 'script': 'super' }],       // superscript/subscript
            [{ 'indent': '-1' }, { 'indent': '+1' }],           // outdent/indent
            [{ 'direction': 'rtl' }],                           // text direction
            [{ 'size': ['small', false, 'large', 'huge'] }],    // custom dropdown
            [{ 'color': [] }, { 'background': [] }],            // dropdown with defaults from theme
            [{ 'font': [] }],
            [{ 'align': [] }],
            ['link'],
            ['clean'],                                          // remove formatting button
            ['video']                                       
        ]
    };

    const htmlFormats = [
        'header',
        'bold', 'italic', 'underline', 'strike', 'blockquote',
        'list', 'bullet', 'indent',
        'link', 'image'
    ];



    const [title, setTitle] = useState('');
    const [content, setContent] = useState('');
    const [banner, setBanner] = useState('');


    const createNewPost = (e) => {
        e.preventDefault();

        const data = new FormData();
        data.set('title', title);
        data.set('content', content);
        data.set('banner', banner);
        console.log(banner)
    }

    return (
        <>
            <div className="p-4 lg:ml-16">
                <div className="p-4 mt-14">

                    <h2 className='text-center font-Play font-semibold text-2xl mb-10'>Create your story...</h2>

                    <div className='grid gap-4 grid-cols-10 h-full'>
                        <div className=' h-fit w-full col-span-10'>
                            <form onSubmit={createNewPost}>

                                <label htmlFor="title" className="block text-sm font-medium text-gray-700">Ttile</label>
                                <div className="mt-1">
                                    <input value={title} onChange={e=>setTitle(e.target.value)} type='text' id="title" name="title" className="resize-none mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm" placeholder="Title goes here" required></input>
                                </div>


                                <label htmlFor='image-upload' className="mt-6 mb-2 block text-sm font-medium text-gray-700">Select a banner</label>
                                <input type="file" onChange={e => setBanner(e.target.files)} id='image-upload' name='banner' accept="image/*" className='rounded-md' required></input>

                                <label htmlFor='body' className="mt-6 mb-2 block text-sm font-medium text-gray-700">Body</label>
                                <div>

                                <ReactQuill value={content} onChange={newValue => setContent(newValue)}  modules={modules} htmlFormats={htmlFormats} id="body" placeholder='Type Content...' ></ReactQuill>
                                </div>

                                <button type="submit" className="mt-8 text-white bg-gradient-to-br from-green-400 to-blue-600 hover:bg-gradient-to-bl focus:ring-4 focus:outline-none focus:ring-green-200 dark:focus:ring-green-800 font-medium rounded-lg text-sm px-5 py-2.5 text-center mr-2 mb-2">Create</button>

                            </form>
                        </div>
                    </div>
                </div>
            </div >
        </>
    )
}

export default CreatePost

我已经尝试过参考相关问题的解决方案,但都没有效果。


解决方案

1. 把modules和htmlFormats移到组件外部

当前你在组件内部定义这两个对象,每次组件状态更新(比如输入标题触发重渲染)时,它们会被重新创建,导致ReactQuill检测到属性变化后重新初始化,出现编辑器消失的问题。修复后代码如下:

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

// 移到组件外部,避免每次渲染重新创建
const modules = {
    toolbar: [
        ['bold', 'italic', 'underline', 'strike'],
        ['blockquote', 'code-block'],
        [{ 'header': [1, 2, 3, 4, 5, 6, false] }],
        [{ 'list': 'ordered' }, { 'list': 'bullet' }],
        [{ 'script': 'sub' }, { 'script': 'super' }],
        [{ 'indent': '-1' }, { 'indent': '+1' }],
        [{ 'direction': 'rtl' }],
        [{ 'size': ['small', false, 'large', 'huge'] }],
        [{ 'color': [] }, { 'background': [] }],
        [{ 'font': [] }],
        [{ 'align': [] }],
        ['link'],
        ['clean'],
        ['video']                                       
    ]
};

const htmlFormats = [
    'header',
    'bold', 'italic', 'underline', 'strike', 'blockquote',
    'list', 'bullet', 'indent',
    'link', 'image'
];

const CreatePost = () => {
    // 组件内部代码保持不变
}

2. 修复文件上传的状态存储

你当前把banner设为e.target.files(FileList对象),属于引用类型,可能导致React状态检测异常。改为存储单个文件:

<input 
    type="file" 
    onChange={e => setBanner(e.target.files[0])}  // 取选中的第一个文件
    id='image-upload' 
    name='banner' 
    accept="image/*" 
    className='rounded-md' 
    required
></input>

3. 修正ReactQuill的格式属性名

ReactQuill的格式配置属性是formats,不是你写的htmlFormats,这个错误也可能导致编辑器异常:

<ReactQuill 
    value={content} 
    onChange={newValue => setContent(newValue)}  
    modules={modules} 
    formats={htmlFormats}  // 修正属性名
    id="body" 
    placeholder='Type Content...' 
></ReactQuill>

4. 检查版本兼容性

确保ReactQuill版本和React版本兼容,React 18需要使用react-quill@2.0.0及以上版本,可通过以下命令更新:

npm install react-quill@latest

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 23:06:35