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

ReactQuill提及功能失效:输入@无列表,加依赖后编辑器消失

修复ReactQuill提及功能失效及文本框消失问题

问题根源

  1. 人员列表未实时同步:原代码中useEffect仅在组件挂载时执行一次,当父组件传入的props.getPeople更新时,people状态不会随之更新,导致提及功能始终使用初始空数组。
  2. useMemo依赖缺失:modules的useMemo依赖为空,source函数捕获的是组件初始化时的people值,即便后续people更新,modules也不会重新生成,提及功能无法获取最新人员数据。
  3. 未定义formats:代码中使用了formats但未声明,这会导致ReactQuill渲染失败,表现为文本框消失。

修复方案

  1. 同步人员列表:修改useEffect的依赖项为props.getPeople,确保people状态随传入数据更新:
useEffect(() => {
  setPeople(props.getPeople || []);
}, [props.getPeople]);
  1. 补充格式定义与useMemo依赖:

    • 声明包含mention在内的所需格式,保证ReactQuill能正确识别提及功能:
    const formats = [
      'font', 'size', 'bold', 'italic', 'underline', 'strike', 'blockquote',
      'list', 'bullet', 'align', 'color', 'background', 'image', 'mention'
    ];
    
    • 在useMemo的依赖数组中加入people,确保modules在人员列表变化时重新生成:
    const modules = useMemo(/* ... */, [people]);
    
  2. 优化提及匹配逻辑:用数组filter方法简化匹配代码,同时避免空值报错:

source: (searchTerm, renderList, mentionChar) => {
  if (mentionChar !== "@") return;
  let matchingPeople = people;
  if (searchTerm.length > 0) {
    matchingPeople = people.filter(person => 
      person.value.toLowerCase().includes(searchTerm.toLowerCase())
    );
  }
  renderList(matchingPeople, searchTerm);
}

修改后的完整代码

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

const RichText = (props) => {
  const [people, setPeople] = useState([]);
  const reactQuillRef = useRef(null);

  useEffect(() => {
    setPeople(props.getPeople || []);
  }, [props.getPeople]);

  const formats = [
    'font', 'size', 'bold', 'italic', 'underline', 'strike', 'blockquote',
    'list', 'bullet', 'align', 'color', 'background', 'image', 'mention'
  ];

  const modules = useMemo(
    () => ({
      toolbar: [
        [{ font: [] }],
        [{ size: ["small", false, "large", "huge"] }],
        ["bold", "italic", "underline", "strike", "blockquote"],
        [{ list: "ordered" }, { list: "bullet" }],
        [{ align: [] }],
        [{ color: [] }, { background: [] }],
        ["image"],
        ["clean"],
      ],
      mention: {
        allowedChars: /^[A-Za-z\sÅÄÖåäö]*$/,
        mentionDenotationChars: ["@"],
        spaceAfterInsert: true,
        source: (searchTerm, renderList, mentionChar) => {
          if (mentionChar !== "@") return;
          let matchingPeople = people;
          if (searchTerm.length > 0) {
            matchingPeople = people.filter(person => 
              person.value.toLowerCase().includes(searchTerm.toLowerCase())
            );
          }
          renderList(matchingPeople, searchTerm);
        },
      },
    }),
    [people]
  );
    
  return (
    <ReactQuill
      defaultValue={props.defaultValue || ""}
      value={props.value || ""}
      theme="snow"
      ref={reactQuillRef}
      placeholder={props.placeholder}
      className={`note_input`}
      formats={formats}
      modules={modules}
      onChange={(content, delta, source, editor) => {
        props.setValue(content, delta, source, editor);
      }}
    />
  );
};

export default RichText;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 19:05:22