如何使用Rest API中的内容创建Draft.js编辑器?

问题描述

我正在尝试使用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

我会在您的渲染器中添加nullundefined检查中的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>