问题描述
我正在尝试使用Draft.js创建一个文本编辑器,并且希望它以一些内容启动。内容来自我也创建的rest API,但是在使其正常工作时遇到了一些麻烦。编辑器本身可以正常工作,但是当我尝试使用内容启动它时,它将不再起作用。
我试图实现这一目标的方法是使用editorState
创建createWithContent()
,但出现错误:
TypeError:无法读取未定义的属性“ getSelection”。
我相信可能是使用'getSelection'函数的函数试图在创建之前editorState
进行访问,但是,我不确定如何修复它。
这是我的编辑器类:
import React,{useState,Component} from 'react';
import {Editor,EditorState,RichUtils,ContentState,convertFromHTML} from 'draft-js';
import axios from "axios";
class MyEditor extends Component {
constructor(props) {
super(props);
this.state = {}
}
componentDidMount() {
axios.get(`http://localhost:8080/BackendWiki/api/brands/Rolex`)
.then(res => {
const brand = res.data;
console.log(res.data)
if (brand) {
const blocksFromHTML = convertFromHTML(brand.description);
const state = ContentState.createFromBlockArray(
blocksFromHTML.contentBlocks,blocksFromHTML.entityMap,);
this.setState({editorState: EditorState.createWithContent(state)})
} else {
this.setState({editorState: EditorState.createEmpty()});
}
}
)
}
handleKeyCommand(command,editorState) {
const newState = RichUtils.handleKeyCommand(editorState,command);
if (newState) {
this.onChange(newState);
return 'handled';
}
return 'not-handled';
}
_onBoldClick(e) {
e.preventDefault();
this.onChange(RichUtils.toggleInlinestyle(this.state.editorState,'BOLD'));
}
_isActive(style) {
const currentFocus = this.state.editorState.getSelection().getFocusKey()
//currentStyle is a map of currently applied style to selected text
const currentStyle = this.state.editorState.getCurrentInlinestyle(currentFocus);
//check if current style is among the style map.
return currentStyle.has(style);
};
render() {
return (
<div>
<button
className={this._isActive("BOLD") ? "bg-blue-700 text-white font-bold py-2 px-4 rounded" : 'bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded'}
onMouseDown={this._onBoldClick.bind(this)}
isActive={"BOLD"}>Bold
</button>
<Editor
editorState={this.state.editorState}
handleKeyCommand={this.handleKeyCommand}
onChange={this.onChange}
/>
</div>
);
}
}
export default MyEditor;
这是错误:
Uncaught TypeError: Cannot read property 'getSelection' of undefined
at MyEditor._isActive (editor.js:52)
at MyEditor.render (editor.js:63)
at finishClassComponent (react-dom.development.js:17160)
at updateClassComponent (react-dom.development.js:17110)
at beginWork (react-dom.development.js:18620)
at HTMLUnkNownElement.callCallback (react-dom.development.js:188)
at Object.invokeGuardedCallbackDev (react-dom.development.js:237)
at invokeGuardedCallback (react-dom.development.js:292)
at beginWork$1 (react-dom.development.js:23203)
at performunitOfWork (react-dom.development.js:22154)
at workLoopSync (react-dom.development.js:22130)
at performSyncWorkOnRoot (react-dom.development.js:21756)
at scheduleUpdateOnFiber (react-dom.development.js:21188)
at updateContainer (react-dom.development.js:24373)
at react-dom.development.js:24758
at unbatchedUpdates (react-dom.development.js:21903)
at legacyRenderSubtreeIntoContainer (react-dom.development.js:24757)
at Object.render (react-dom.development.js:24840)
at Module../src/index.js (index.js:12)
at __webpack_require__ (bootstrap:784)
at fn (bootstrap:150)
at Object.1 (tailwind.output.css?5033:45)
at __webpack_require__ (bootstrap:784)
at checkDeferredModules (bootstrap:45)
at Array.webpackJsonpCallback [as push] (bootstrap:32)
at main.chunk.js:1
_isActive @ editor.js:52
render @ editor.js:63
finishClassComponent @ react-dom.development.js:17160
updateClassComponent @ react-dom.development.js:17110
beginWork @ react-dom.development.js:18620
callCallback @ react-dom.development.js:188
invokeGuardedCallbackDev @ react-dom.development.js:237
invokeGuardedCallback @ react-dom.development.js:292
beginWork$1 @ react-dom.development.js:23203
performunitOfWork @ react-dom.development.js:22154
workLoopSync @ react-dom.development.js:22130
performSyncWorkOnRoot @ react-dom.development.js:21756
scheduleUpdateOnFiber @ react-dom.development.js:21188
updateContainer @ react-dom.development.js:24373
(anonymous) @ react-dom.development.js:24758
unbatchedUpdates @ react-dom.development.js:21903
legacyRenderSubtreeIntoContainer @ react-dom.development.js:24757
render @ react-dom.development.js:24840
./src/index.js @ index.js:12
__webpack_require__ @ bootstrap:784
fn @ bootstrap:150
1 @ tailwind.output.css?5033:45
__webpack_require__ @ bootstrap:784
checkDeferredModules @ bootstrap:45
webpackJsonpCallback @ bootstrap:32
(anonymous) @ main.chunk.js:1
index.js:1 The above error occurred in the <MyEditor> component:
in MyEditor (at Brand.js:41)
in div (at Brand.js:36)
in Brand (created by Context.Consumer)
in Route (at App.js:16)
in div (at App.js:13)
in App (at src/index.js:14)
in Router (created by browserRouter)
in browserRouter (at src/index.js:13)
Consider adding an error boundary to your tree to customize error handling behavior.
console.<computed> @ index.js:1
logCapturedError @ react-dom.development.js:19527
logError @ react-dom.development.js:19564
update.callback @ react-dom.development.js:20708
callCallback @ react-dom.development.js:12490
commitUpdateQueue @ react-dom.development.js:12511
commitLifeCycles @ react-dom.development.js:19883
commitLayoutEffects @ react-dom.development.js:22803
callCallback @ react-dom.development.js:188
invokeGuardedCallbackDev @ react-dom.development.js:237
invokeGuardedCallback @ react-dom.development.js:292
commitRootImpl @ react-dom.development.js:22541
unstable_runWithPriority @ scheduler.development.js:653
runWithPriority$1 @ react-dom.development.js:11039
commitRoot @ react-dom.development.js:22381
finishSyncRender @ react-dom.development.js:21807
performSyncWorkOnRoot @ react-dom.development.js:21793
scheduleUpdateOnFiber @ react-dom.development.js:21188
updateContainer @ react-dom.development.js:24373
(anonymous) @ react-dom.development.js:24758
unbatchedUpdates @ react-dom.development.js:21903
legacyRenderSubtreeIntoContainer @ react-dom.development.js:24757
render @ react-dom.development.js:24840
./src/index.js @ index.js:12
__webpack_require__ @ bootstrap:784
fn @ bootstrap:150
1 @ tailwind.output.css?5033:45
__webpack_require__ @ bootstrap:784
checkDeferredModules @ bootstrap:45
webpackJsonpCallback @ bootstrap:32
(anonymous) @ main.chunk.js:1
react-dom.development.js:22665 Uncaught TypeError: Cannot read property 'getSelection' of undefined
at MyEditor._isActive (editor.js:52)
at MyEditor.render (editor.js:63)
at finishClassComponent (react-dom.development.js:17160)
at updateClassComponent (react-dom.development.js:17110)
at beginWork (react-dom.development.js:18620)
at HTMLUnkNownElement.callCallback (react-dom.development.js:188)
at Object.invokeGuardedCallbackDev (react-dom.development.js:237)
at invokeGuardedCallback (react-dom.development.js:292)
at beginWork$1 (react-dom.development.js:23203)
at performunitOfWork (react-dom.development.js:22154)
at workLoopSync (react-dom.development.js:22130)
at performSyncWorkOnRoot (react-dom.development.js:21756)
at scheduleUpdateOnFiber (react-dom.development.js:21188)
at updateContainer (react-dom.development.js:24373)
at react-dom.development.js:24758
at unbatchedUpdates (react-dom.development.js:21903)
at legacyRenderSubtreeIntoContainer (react-dom.development.js:24757)
at Object.render (react-dom.development.js:24840)
at Module../src/index.js (index.js:12)
at __webpack_require__ (bootstrap:784)
at fn (bootstrap:150)
at Object.1 (tailwind.output.css?5033:45)
at __webpack_require__ (bootstrap:784)
at checkDeferredModules (bootstrap:45)
at Array.webpackJsonpCallback [as push] (bootstrap:32)
at main.chunk.js:1
我是否缺少某些东西,或者有更好的方法来实现这一目标? 谢谢!
解决方法
其背后的原因基于您的堆栈跟踪,调用_isActive()
函数将在this.state.editorState.getSelection()
仍为this.state.editorState
时调用undefined
。
我会在您的渲染器中添加null
或undefined
检查中的this.state.editorState
。
render() {
return this.state.editorState ?
<div>
<button className={this._isActive("BOLD") ? "bg-blue-700 text-white font-bold py-2 px-4 rounded" : 'bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded'}
onMouseDown={this._onBoldClick.bind(this)}
isActive={"BOLD"}>Bold
</button>
<Editor editorState={this.state.editorState}
handleKeyCommand={this.handleKeyCommand}
onChange={this.onChange} />
</div> : null
}
此外,您可以在三元运算符中添加某种加载组件,而不是null
,这样看起来更好,直到API调用仍在进行中为止。
this.state.editorState ?
<div> {/* your editor */} </div> :
<span>Loading...</span>