ReactQuill提及功能失效:输入@无列表,加依赖后编辑器消失
修复ReactQuill提及功能失效及文本框消失问题
问题根源
- 人员列表未实时同步:原代码中
useEffect仅在组件挂载时执行一次,当父组件传入的props.getPeople更新时,people状态不会随之更新,导致提及功能始终使用初始空数组。 - useMemo依赖缺失:
modules的useMemo依赖为空,source函数捕获的是组件初始化时的people值,即便后续people更新,modules也不会重新生成,提及功能无法获取最新人员数据。 - 未定义
formats:代码中使用了formats但未声明,这会导致ReactQuill渲染失败,表现为文本框消失。
修复方案
- 同步人员列表:修改
useEffect的依赖项为props.getPeople,确保people状态随传入数据更新:
useEffect(() => { setPeople(props.getPeople || []); }, [props.getPeople]);
补充格式定义与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]);- 声明包含
优化提及匹配逻辑:用数组
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
相关产品推荐
相关产品推荐

