如何在react-hook-form中实现SlateJS编辑器自动聚焦与表单重置
解决SlateJS与react-hook-form集成的聚焦和重置问题
核心问题分析
你的代码存在语法错误+缺少value同步逻辑,直接导致聚焦和重置功能失效:
CustomEditor的forwardRef参数解构错误,无法正确接收props与refCustomEditorController中ref回调存在语法错误- Slate的
initialValue仅在首次渲染生效,未监听外部value变化同步编辑器内容
步骤1:修复基础语法错误
修正CustomEditor的参数结构
forwardRef的第一个参数是完整props对象,而非单独解构的属性:
const CustomEditor = React.forwardRef<any, TextEditorProps>( ({ name, value, onValueChange }, ref) => { // 修正:props为整体对象 const editor: MyEditor = useMemo(() => withHistory(withReact(createEditor())), []); useImperativeHandle(ref, () => ({ focus: () => { console.log("set focus via imperative handle"); ReactEditor.focus(editor); }, })); // 后续逻辑... } );
修正CustomEditorController的ref回调
<CustomEditor ref={(el: any) => field.ref(el)} // 修正:括号匹配错误 name={field.name} value={field.value} onValueChange={field.onChange} />
步骤2:实现表单重置同步
Slate的initialValue仅在编辑器初始化时加载内容,react-hook-form调用reset()时,外部value更新但编辑器不会自动同步。需通过useEffect监听value变化,手动重置编辑器内容:
const CustomEditor = React.forwardRef<any, TextEditorProps>( ({ name, value, onValueChange }, ref) => { const editor: MyEditor = useMemo(() => withHistory(withReact(createEditor())), []); // 监听外部value变化,同步编辑器内容 useEffect(() => { // 跳过初始渲染的重复执行 if (!editor.children.length) return; // 对比当前编辑器内容与目标value,不同则重置 const currentContent = JSON.stringify(editor.children); const targetContent = JSON.stringify(value); if (currentContent !== targetContent) { // 清空编辑器并插入新内容 Transforms.delete(editor, { at: { anchor: Editor.start(editor, []), focus: Editor.end(editor, []), }, }); Transforms.insertNodes(editor, value); } }, [editor, value]); useImperativeHandle(ref, () => ({ focus: () => { ReactEditor.focus(editor); }, })); return ( <Slate editor={editor} initialValue={value} onValueChange={onValueChange} > <Editable name={name} /> </Slate> ); } );
步骤3:验证聚焦功能
修正后,react-hook-form的initialFocus或setFocus可通过field.ref调用你暴露的focus方法,激活Slate编辑器聚焦。示例调用代码:
// 在表单组件中使用setFocus触发聚焦 const { setFocus } = useFormContext(); const handleFocusEditor = () => { setFocus('editor'); };
关键注意点
- 确保
useImperativeHandle正确暴露focus方法,且field.ref绑定到组件ref上 - Slate编辑器内容为内部状态,外部value变化必须手动同步,不能依赖
initialValue - 内容对比用
JSON.stringify是简易方案,复杂场景可替换为Slate内置的Editor.equals方法优化
内容的提问来源于stack exchange,提问作者caprica
相关产品推荐
相关产品推荐

