通过Props传递的Tiptap编辑器绑定事件失效问题求助
问题原因与解决方案
核心问题
报错的根本原因是编辑器实例未初始化完成,或组件渲染时editor为null就尝试绑定事件/调用方法。useEditor返回的实例在组件初始渲染阶段可能还处于未就绪状态,直接在组件顶层调用editor.on会触发空指针错误;而editor.chain()能正常工作是因为点击事件触发时,编辑器已经完成初始化。
解决方案:用useEffect安全绑定事件
在子组件中通过useEffect监听editor实例,确保实例存在后再绑定事件,同时在组件卸载时清理事件监听(避免内存泄漏)。
加粗按钮组件示例(解决active状态监听)
import { useEffect, useState } from 'react'; const BoldBtn = ({ editor }) => { const [isBoldActive, setIsBoldActive] = useState(false); useEffect(() => { // 编辑器实例不存在时直接返回 if (!editor) return; // 定义状态更新函数 const updateActiveState = () => { setIsBoldActive(editor.isActive('bold')); }; // 绑定事件监听 editor.on('update', updateActiveState); editor.on('selectionUpdate', updateActiveState); // 初始执行一次,确保渲染时状态正确 updateActiveState(); // 组件卸载时解绑事件,防止内存泄漏 return () => { editor.off('update', updateActiveState); editor.off('selectionUpdate', updateActiveState); }; }, [editor]); // 依赖editor实例,实例变化时重新绑定 const handleClick = () => { // 用可选链避免editor为null时报错 editor?.chain().focus().toggleBold().run(); }; return ( <button onClick={handleClick} className={isBoldActive ? 'active-btn' : ''} > 加粗 </button> ); }; export default BoldBtn;
链接按钮组件示例(获取并更新链接href)
import { useEffect, useState } from 'react'; const LinkBtn = ({ editor }) => { const [isLinkActive, setIsLinkActive] = useState(false); const [currentHref, setCurrentHref] = useState(''); useEffect(() => { if (!editor) return; const updateLinkState = () => { const linkAttrs = editor.getAttributes('link'); setIsLinkActive(editor.isActive('link')); setCurrentHref(linkAttrs.href || ''); }; editor.on('update', updateLinkState); editor.on('selectionUpdate', updateLinkState); updateLinkState(); return () => { editor.off('update', updateLinkState); editor.off('selectionUpdate', updateLinkState); }; }, [editor]); const handleUpdateLink = (newHref) => { editor?.chain().focus().setLink({ href: newHref }).run(); }; return ( <div className="link-btn-group"> <button className={isLinkActive ? 'active-btn' : ''} > 链接 </button> {isLinkActive && ( <input type="text" value={currentHref} onChange={(e) => handleUpdateLink(e.target.value)} placeholder="输入链接地址" /> )} </div> ); }; export default LinkBtn;
关键注意事项
- 依赖监听:将
editor作为useEffect的依赖项,确保编辑器实例变化时重新绑定事件 - 事件清理:必须在
useEffect的返回函数中解绑事件,避免编辑器销毁后仍触发回调导致报错 - 可选链保护:调用
editor相关方法时加?.,防止实例未就绪时报错
内容的提问来源于stack exchange,提问作者samadfullstack
相关产品推荐
相关产品推荐

