![](/img/trans.png)
[英]filterDescendants and findDescendant with slate.js
[英]Slate.js throws an error when inserting a new node at selected region
相關代碼塊:
<Slate editor={editor} value={value} onChange={value => {
setValue(value);
const { selection } = editor;
// if nothing is currently selected under the cursor
if (selection && Range.isCollapsed(selection)) {
const [start] = Range.edges(selection);
// if the two characters beforce the cursor are {{, select them and replace with a template block
const before = Editor.before(editor, start, {distance: 2})
const beforeRange = before && Editor.range(editor, before, start)
const beforeText = beforeRange && Editor.string(editor, beforeRange)
const beforeMatch = beforeText && beforeText.match(/\{\{/);
if (beforeMatch) {
Transforms.select(editor, beforeRange as Location);
insertTemplateBlock(editor, {name: "test"})
}
}
}}>
...
</Slate>
export const insertTemplateBlock = (editor: Editor, {name, opts, defaultValue}: TemplateBlockProps) => {
const templateBlock = { type: "template-block", name, opts, defaultValue, children: [{text: ''}] }
Transforms.insertNodes(editor, templateBlock);
Transforms.move(editor);
}
具體來說,它總是在insertTemplateBlock
function 內的第二行中斷,並給出如下錯誤:
Cannot find a descendant at path [0,2] in node: {"children":[{"type":"paragraph","children":[{"text":"Thing is working {{"}]}],"operations":[{"type":"insert_text","path":[0,0],"offset":18,"text":"{"},{"type":"set_selection","properties":{"anchor":{"path":[0,0],"offset":19}},"newProperties":{"anchor":{"path":[0,0],"offset":17}}},{"type":"remove_text","path":[0,0],"offset":17,"text":"{{"},{"type":"insert_node","path":[0,1],"node":{"type":"template-block","name":"test","children":[{"text":""}]}},{"type":"set_selection","properties":{"anchor":{"path":[0,0],"offset":17},"focus":{"path":[0,0],"offset":17}},"newProperties":{"anchor":{"path":[0,1,0],"offset":0},"focus":{"path":[0,1,0],"offset":0}}},{"type":"insert_node","path":[0,2],"node":{"text":""}},{"type":"set_selection","properties":{"anchor":{"path":[0,1,0],"offset":0},"focus":{"path":[0,1,0],"offset":0}},"newProperties":{"anchor":{"path":[0,2],"offset":0},"focus":{"path":[0,2],"offset":0}}}],"selection":{"anchor":{"path":[0,2],"offset":0},"focus":{"path":[0,2],"offset":0}},"marks":null,"history":{"undos":[[{"type":"set_selection","properties":null,"newProperties":{"anchor":{"path":[0,0],"offset":0},"focus":{"path":[0,0],"offset":0}}}],[{"type":"insert_text","path":[0,0],"offset":0,"text":"T"},{"type":"insert_text","path":[0,0],"offset":1,"text":"h"},{"type":"insert_text","path":[0,0],"offset":2,"text":"i"},{"type":"insert_text","path":[0,0],"offset":3,"text":"n"},{"type":"insert_text","path":[0,0],"offset":4,"text":"g"},{"type":"insert_text","path":[0,0],"offset":5,"text":" "},{"type":"insert_text","path":[0,0],"offset":6,"text":"i"},{"type":"insert_text","path":[0,0],"offset":7,"text":"s"},{"type":"insert_text","path":[0,0],"offset":8,"text":" "},{"type":"insert_text","path":[0,0],"offset":9,"text":"w"},{"type":"insert_text","path":[0,0],"offset":10,"text":"o"},{"type":"insert_text","path":[0,0],"offset":11,"text":"r"},{"type":"insert_text","path":[0,0],"offset":12,"text":"k"},{"type":"insert_text","path":[0,0],"offset":13,"text":"i"},{"type":"insert_text","path":[0,0],"offset":14,"text":"n"},{"type":"insert_text","path":[0,0],"offset":15,"text":"g"},{"type":"insert_text","path":[0,0],"offset":16,"text":" "},{"type":"set_selection","properties":null,"newProperties":{"anchor":{"path":[0,0],"offset":17},"focus":{"path":[0,0],"offset":17}}}],[{"type":"insert_text","path":[0,0],"offset":17,"text":"{"},{"type":"insert_text","path":[0,0],"offset":18,"text":"{"},{"type":"set_selection","properties":{"anchor":{"path":[0,0],"offset":19}},"newProperties":{"anchor":{"path":[0,0],"offset":17}}},{"type":"remove_text","path":[0,0],"offset":17,"text":"{{"},{"type":"insert_node","path":[0,1],"node":{"type":"template-block","name":"test","children":[{"text":""}]}},{"type":"set_selection","properties":{"anchor":{"path":[0,0],"offset":17},"focus":{"path":[0,0],"offset":17}},"newProperties":{"anchor":{"path":[0,1,0],"offset":0},"focus":{"path":[0,1,0],"offset":0}}},{"type":"insert_node","path":[0,2],"node":{"text":""}},{"type":"set_selection","properties":{"anchor":{"path":[0,1,0],"offset":0},"focus":{"path":[0,1,0],"offset":0}},"newProperties":{"anchor":{"path":[0,2],"offset":0},"focus":{"path":[0,2],"offset":0}}}]],"redos":[]}}
這在他們提到的例子中沒有發生,它使用了類似的邏輯。 任何幫助,將不勝感激!
代碼沙盒:https://codesandbox.io/s/elastic-turing-dv9bm?file=/src/App.tsx
更新:我發現可以通過將插入邏輯(當前在 if 語句中)移動到useEffect
掛鈎來避免這個問題,具體取決於包含選擇的target
,類似於 Slate 的提及示例的工作方式。 但是,我仍然很想知道為什么 Slate 會像我以問題陳述的方式編寫它時那樣中斷。
當您使用useMemo
時,該問題與渲染有關,您應該使用useRef
:
const editorRef = useRef()
if (!editorRef.current) editorRef.current = withReact(createEditor())
const editor = editorRef.current
我認為您的問題源於<Slate>
是上下文提供者這一事實,您實際上應該使用嵌套的<Editable>
組件來處理事件 - 在您的情況下為onKeyDown
。 在您提到的具體示例中,我相信您遇到了嵌套Editable
組件不會發生的競爭條件。 請參閱文檔中演練下的安裝 Slate 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.