问题描述
当我从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"));
解决方法
我已经解决了这个问题,我将我的工作代码留在这里,希望它可以对某人有所帮助,
我当时正在使用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,});
,
当我自己安装 immutable 并更新到 4.0 时,这种情况开始发生
当我删除它并让draft-js安装版本“3.7.6”时工作