创建新块 + 复制时不可变/Draftjs 错误“block.getKey 不是函数”
Posted
技术标签:
【中文标题】创建新块 + 复制时不可变/Draftjs 错误“block.getKey 不是函数”【英文标题】:Immutable / Draftjs Error 'block.getKey is not a function' when creating new block + reproduction 【发布时间】:2021-01-06 12:19:57 【问题描述】:当我从 Immutable OrderedMap 到 Array 创建新的 contentState 时,即使提供了密钥,我也会从 Draftjs 获得 block.getKey is not a function
...
我在 draftjs github 上发现了一个帖子,暗示这可能是一个错误,但它是从 2016 年开始的, 想知道是否有人有他们可以建议的解决方案或解决方法...
这是一个codeandbox复制的链接 https://codesandbox.io/s/blockgetkey-error-reproduction-h75mf?file=/src/index.js
import React from "react";
import ReactDOM from "react-dom";
import
List as ImmutableList,
Repeat as ImmutableRepeat,
Map as ImmutableMap,
OrderedMap
from "immutable";
import
Editor,
EditorState,
ContentBlock,
ContentState,
genKey,
CharacterMetadata
from "draft-js";
function MyEditor()
const [editorState, setEditorState] = React.useState(
EditorState.createEmpty()
);
const editor = React.useRef(null);
function focusEditor()
editor.current.focus();
React.useEffect(() =>
focusEditor();
, []);
return (
<div onClick=focusEditor>
<Editor
ref=editor
editorState=editorState
onChange=(editorState) => setEditorState(editorState)
/>
<button
onClick=() =>
// const newBlockMap = contentState.getBlockMap().set(newBlock.key, newBlock)
const charData = CharacterMetadata.create();
const text1 = "This was the test value";
const contentState = editorState.getCurrentContent();
const blockMap = contentState.getBlockMap();
const newBlock = new ContentBlock(
key: genKey(),
type: "Img",
text: text1,
characterList: ImmutableList(
ImmutableRepeat(charData, text1.length)
),
data: ImmutableMap( content: "foo bear" )
);
const insertBefore = OrderedMap().withMutations((r) =>
blockMap.forEach((k, v) =>
console.log("k ", k);
console.log("v ", v);
if (3 === k)
r.set(newBlock.key, newBlock);
r.set(k, v);
);
);
let newcontentState = ContentState.createFromBlockArray(
insertBefore.toArray()
).set("selectionAfter", contentState.getSelectionAfter());
const newEditorState = EditorState.push(
editorState,
newcontentState,
"insert-fragment"
);
setEditorState(
...editorState,
editorState: newEditorState
);
>
Add New Block
</button>
</div>
);
function App()
return (
<div>
<h3>Test</h3>
<MyEditor />
</div>
);
ReactDOM.render(<App />, document.getElementById("root"));
【问题讨论】:
【参考方案1】:当我自己安装 immutable 并更新到 4.0 时,这开始发生
当我删除它并让 Draft-js 安装版本“3.7.6”时工作
【讨论】:
【参考方案2】:我已经解决了这个问题,我会把我的工作代码留在这里,希望它可以帮助别人,
我正在使用 Immutebale 突变来尝试创建一个新的 BlockMap,但它似乎没有以 Draftjs 可以理解的方式构建。我没有使用循环,而是使用blockMap.toSeq().takeUntil((v)
和blockMap.toSeq().skipUntil((v)
来拆分当前时钟状态,添加新块并重新组装它。
我还将contnetState.createFromArray()
更改为contnetState.merge()
,这样更干净!因为它允许您合并不可变的 Map 对象而无需转换。
e.preventDefault();
e.stopPropagation();
const getCurrentBlock = () =>
const selectionState = editorState.getSelection();
const contentState = editorState.getCurrentContent();
const block = contentState.getBlockForKey(selectionState.getStartKey());
return block;
;
let pivotBlockKey = getCurrentBlock().key
const contnetState = editorState.getCurrentContent();
const blockMap = contnetState.getBlockMap();
const block = blockMap.get(pivotBlockKey);
const blocksBefore = blockMap.toSeq().takeUntil((v) => (v === block));
const blocksAfter = blockMap.toSeq().skipUntil((v) => (v === block)).rest();
const charData = CharacterMetadata.create()
const text1 = "This was the test value"
const newBlockKey = genKey()
const newBlock = new ContentBlock(
key: newBlockKey,
type: "header-one",
text: text1,
characterList: ImmutableList(ImmutableRepeat(charData, text1.length)),
data: ImmutableMap( content: "foo bear" )
)
const newBlockMap = blocksBefore.concat(
[[pivotBlockKey, block], [newBlockKey, newBlock]],
blocksAfter
).toOrderedMap();
let newContnetState = contnetState.merge(
blockMap: newBlockMap,
selectionBefore: contentState.getSelectionBefore()
)
const newEditorState = EditorState.push(
editorState,
newContnetState,
'insert-fragment'
);
setState(
...state,
editorState: newEditorState,
);
【讨论】:
以上是关于创建新块 + 复制时不可变/Draftjs 错误“block.getKey 不是函数”的主要内容,如果未能解决你的问题,请参考以下文章
DraftJs:不变违规:使用 convertToRaw 时块不是 BlockNode