PlateController 是一个可选的 provider 组件,用于从各自的 Plate 组件外部访问特定的 Plate Stores。
PlateController Store
使用模式
通过 ID 访问特定编辑器
PlateController 可用于使用其 id 访问特定编辑器的 store。请注意,如果找不到匹配的编辑器,将返回一个不可变的回退编辑器。
const App = withHoc(PlateController, () => {
const mainEditor = useEditorRef('main');
useEffect(() => {
if (!mainEditor.isFallback) {
console.info('Editor mounted', mainEditor);
}
}, [mainEditor]);
return (
<>
<Plate editor={createPlateEditor({ id: 'main' })}>
<PlateContent />
</Plate>
<Plate editor={createPlateEditor({ id: 'secondary' })}>
<PlateContent />
</Plate>
</>
);
});活动编辑器
如果在 PlateController 内部使用 useEditorRef 等钩子时没有显式指定 id,它们将解析为当前活动的编辑器。
活动编辑器的确定方式如下:
- 如果某个编辑器已获得焦点,则返回最后一个这样的编辑器。
- 如果某个编辑器是主要编辑器,则返回第一个挂载的这样的编辑器。
- 否则,返回一个不可变的回退编辑器。
const App = withHoc(PlateController, () => {
const activeEditorId = useEditorId();
const isFallback = !useEditorMounted();
const message = isFallback
? '请聚焦一个编辑器'
: `活动编辑器:${activeEditorId}`;
return (
<main>
<p>{message}</p>
<Plate editor={createPlateEditor({ id: 'main', primary: false })}>
<PlateContent />
</Plate>
<Plate editor={createPlateEditor({ id: 'secondary', primary: false })}>
<PlateContent />
</Plate>
</main>
);
});处理回退编辑器
当在 PlateController 内部调用的钩子无法找到匹配的 Plate Store 时,它将使用 Plate Store 的默认值。editor 的默认值是 createPlateFallbackEditor()。回退编辑器就像一个没有插件的空 Plate 编辑器,但如果它收到 Slate 操作,则会抛出运行时错误(即它是不可变的,不能用于转换)。
这样做的原因是确保查询编辑器的代码(例如确定工具栏按钮是否处于活动状态)在出现问题时静默失败并返回合理的默认值,而转换编辑器的代码(例如按下工具栏按钮)则大声失败并显示错误。
有两种方法可以确定您是否正在使用回退编辑器或真实编辑器:
useEditorMounted如果无法解析到已挂载的编辑器,则返回falseeditor.meta.isFallback对于回退编辑器为true
在 PlateController 内部使用 useEditorRef 等钩子时,您应该编写防御性代码,以确保在出现回退编辑器时能够适当处理。例如,如果 useEditorMounted 返回 false,您可以禁用工具栏按钮,或者如果 editor.meta.isFallback 为 true,则可以忽略事件。
import { KEYS } from 'platejs';
const App = withHoc(PlateController, () => {
const activeEditor = useEditorRef();
const toggleBold = () => {
if (activeEditor.isFallback) return;
activeEditor.tf.toggleMark(KEYS.bold);
};
return (
<main>
<button type="button" onClick={toggleBold}>
Bold
</button>
<Plate editor={createPlateEditor({ id: 'main', primary: false })}>
<PlateContent />
</Plate>
<Plate editor={createPlateEditor({ id: 'secondary', primary: false })}>
<PlateContent />
</Plate>
</main>
);
});const App = withHoc(PlateController, () => {
const activeEditor = useEditorRef();
const isFallback = !useEditorMounted();
const toggleBold = () => {
activeEditor.tf.toggleMark(KEYS.bold);
};
return (
<main>
<button
type="button"
onClick={toggleBold}
disabled={isFallback}
>
Bold
</button>
<Plate editor={createPlateEditor({ id: 'main', primary: false })}>
<PlateContent />
</Plate>
<Plate editor={createPlateEditor({ id: 'secondary', primary: false })}>
<PlateContent />
</Plate>
</main>
);
});