Как мне создать Draft.js редактор с содержимым из rest API?

#javascript #reactjs #axios #draftjs

#javascript #reactjs #axios #draftjs

Вопрос:

Я пытаюсь создать текстовый редактор с помощью Draft.js и я хочу, чтобы он запускался с некоторым содержимым. Содержимое поступает из rest API, который я также создал, но у меня возникли некоторые проблемы с запуском его работы. Сам редактор работает нормально, но когда я пытаюсь запустить его с содержимым, он больше не работает.

Я пытаюсь добиться этого путем создания editorState с createWithContent() помощью, но я получаю сообщение об ошибке:

Ошибка типа: не удается прочитать свойство ‘&etSelection’ из undefined.

Я полагаю, что, возможно, функция, использующая функцию ‘&etSelection’, пытается получить доступ к editorState до ее создания, однако я не уверен, как это исправить.

Это мой класс editor:

 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.&et(`http://localhost:8080/BackendWiki/api/brands/Rolex`)
            .then(res =&&t; {
                    const brand = res.data;
                    console.lo&(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.onChan&e(newState);
            return 'handled';
        }

        return 'not-handled';
    }

    _onBoldClick(e) {
        e.preventDefault();
        this.onChan&e(RichUtils.to&&leInlineStyle(this.state.editorState, 'BOLD'));
    }

    _isActive(style) {
        const currentFocus = this.state.editorState.&etSelection().&etFocusKey()
        //currentStyle is a map of currently applied style to selected text
        const currentStyle = this.state.editorState.&etCurrentInlineStyle(currentFocus);
        //check if current style is amon& the style map.
        return currentStyle.has(style);
    };

    render() {
        return (
            <div&&t;
                <button
                    className={this._isActive("BOLD") ? "b&-blue-700 text-white font-bold py-2 px-4 rounded" : 'b&-blue-500 hover:b&-blue-700 text-white font-bold py-2 px-4 rounded'}
                    onMouseDown={this._onBoldClick.bind(this)}
                    isActive={"BOLD"}&&t;Bold
                </button&&t;
                <Editor
                    editorState={this.state.editorState}
                    handleKeyCommand={this.handleKeyCommand}
                    onChan&e={this.onChan&e}
                /&&t;
            </div&&t;
        );
    }
}

export default MyEditor;

  

И это ошибка:

 Uncau&ht TypeError: Cannot read property '&etSelection' 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 be&inWork (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 be&inWork$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 le&acyRenderSubtreeIntoContainer (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
be&inWork @ react-dom.development.js:18620
callCallback @ react-dom.development.js:188
invokeGuardedCallbackDev @ react-dom.development.js:237
invokeGuardedCallback @ react-dom.development.js:292
be&inWork$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
le&acyRenderSubtreeIntoContainer @ 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&&t; 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 addin& an error boundary to your tree to customize error handlin& behavior.
console.<computed&&t; @ index.js:1
lo&CapturedError @ react-dom.development.js:19527
lo&Error @ 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
le&acyRenderSubtreeIntoContainer @ 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 Uncau&ht TypeError: Cannot read property '&etSelection' 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 be&inWork (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 be&inWork$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 le&acyRenderSubtreeIntoContainer (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
  

Я что-то упускаю или есть лучший способ добиться этого?
Спасибо!

Ответ №1:

Причина этого основана на вашей трассировке стека, когда вызывается _isActive() функция, которая вызывается this.state.editorState.&etSelection() один раз this.state.editorState , по-прежнему undefined .

Я бы добавил null или undefined проверку в вашем рендеринге для this.state.editorState .

 render() {
   return this.state.editorState ?
       <div&&t;
           <button className={this._isActive("BOLD") ? "b&-blue-700 text-white font-bold py-2 px-4 rounded" : 'b&-blue-500 hover:b&-blue-700 text-white font-bold py-2 px-4 rounded'}
                   onMouseDown={this._onBoldClick.bind(this)}
                   isActive={"BOLD"}&&t;Bold
           </button&&t;
           <Editor editorState={this.state.editorState}
                   handleKeyCommand={this.handleKeyCommand}
                   onChan&e={this.onChan&e} /&&t;
       </div&&t; : null
}
  

Кроме того, вы можете добавить какой-нибудь загрузочный компонент вместо null в тернарном операторе, который выглядит лучше, пока вызов API все еще выполняется, например:

 this.state.editorState ?
     <div&&t; {/* your editor */} </div&&t; :
     <span&&t;Loadin&...</span&&t;
  

Комментарии:

1. Черт возьми, это сработало! Я пытался решить эту проблему весь день, спасибо!