Skip to content
This repository has been archived by the owner on Feb 6, 2023. It is now read-only.

Uncaught TypeError: Cannot read property 'getIn' of undefined #2332

Closed
hejtmii opened this issue Feb 25, 2020 · 13 comments
Closed

Uncaught TypeError: Cannot read property 'getIn' of undefined #2332

hejtmii opened this issue Feb 25, 2020 · 13 comments

Comments

@hejtmii
Copy link

hejtmii commented Feb 25, 2020

Do you want to request a feature or report a bug?

Bug

What is the current behavior?

When there are two DraftJS instances on the page, and you start the selection in one and finish it in the second, the editor crashes with the following error:

Uncaught TypeError: Cannot read property 'getIn' of undefined
    at getUpdatedSelectionState (Draft.js:4829)
    at getDraftEditorSelectionWithNodes (Draft.js:4636)
    at getDraftEditorSelection (Draft.js:4590)
    at editOnSelect (Draft.js:4484)

How to reproduce:

It seems that the editor detects the target is a DraftJS based on its markup structure but doesn't check it is its own instance. Therefore the selection handling assumes the existence of the underlying data, but the data is not found in current instance and it fails.

What is the expected behavior?

The editor does not throw an error, and updates the selection towards its end/start.

Which versions of Draft.js, and which browser / OS are affected by this issue? Did this work in previous versions of Draft.js?

Chrome Version 80.0.3987.116 (Official Build) (64-bit)
DraftJS 0.11.4 (latest)

@lavaldi
Copy link

lavaldi commented Mar 20, 2020

I've got the same error when I try to change a checkbox using medium-draft

And Sentry reports it in the file ../node_modules/draft-js/lib/editOnInput.js

https://github.com/facebook/draft-js/blob/792bd3abe9b2c8735e2917af30b3dc9b0055e3ab/src/component/handlers/edit/editOnInput.js#L106-L108

Chrome Version 80.0.3987.132 (Official Build) (64-bit)
Firefox Version 74.0 (64-bit)
DraftJS 0.11.4 (latest)

@lavaldi
Copy link

lavaldi commented Mar 20, 2020

And maybe it's related to issue #2204 because sometimes throw the error Cannot read property 'nodeType' of null in these lines

https://github.com/facebook/draft-js/blob/792bd3abe9b2c8735e2917af30b3dc9b0055e3ab/src/component/handlers/edit/editOnInput.js#L71-L73

🤔

@mrkev
Copy link
Contributor

mrkev commented Mar 24, 2020

Merged #2330 which should deal with Cannot read property 'nodeType' of null. I expect we will still see this getIn error, but FYI (:

@mrkev
Copy link
Contributor

mrkev commented Mar 25, 2020

@kenticomartinh had a look, the exception you're seeing has been fixed already, the changed have just not been published to npm. They'll be there once 0.11.5 comes around:

https://github.com/facebook/draft-js/blob/a9fcbb201de604e040dacb66e67407989a0e2d9b/src/component/selection/getUpdatedSelectionState.js#L40-L46

@lavaldi, the issue you're seeing in editOnInput.js seems to be unrelated. Could you open another issue and just copy your comment there, to track it separately? Put a link to this issue for reference too.

@lavaldi
Copy link

lavaldi commented Mar 25, 2020

@lavaldi, the issue you're seeing in editOnInput.js seems to be unrelated. Could you open another issue and just copy your comment there, to track it separately? Put a link to this issue for reference too.

Sure @mrkev! Done it!

@mrkev mrkev closed this as completed Mar 26, 2020
@davidgolden
Copy link

davidgolden commented Mar 27, 2020

I'm not able to do any editing without receiving this error. Is there any workaround for this until 0.11.5 is published?

UPDATE 1 After downloading 0.11.5 I'm still seeing this issue. The error manifests in different ways on different browsers, but the root of it seems to be "Invalid Selection State". It appears to be some kind of incompatibility with NextJS: https://codesandbox.io/s/reverent-fire-bvogb

UPDATE 2 It appears the cause of this issue is the server rendering one thing with one selection state key, and then the client rendering a with a different key. See #1199 (comment)

@bathientran
Copy link

@davidgolden Did you find a solution regarding using DraftJS with NextJS? I'm still getting this issue and would have to consider moving to a different solution if this is persistent.

@davidgolden
Copy link

@bathientran I did, the trick is to pass in a static key so that it's rendered the same on the server and the client, this is what's working for me (I'm also using markdown-draft-js):

export default function DraftEditor(props) {
    const editorRef = useRef(null);

    const markdown = useRef(markdownToDraft(props.value));
    markdown.current.blocks = markdown.current.blocks.map((b, i) => ({...b, key: `foo-${i}`}));
    const [editorState, setEditorState] = useState(EditorState.createWithContent(convertFromRaw(markdown.current)));

    function handleChange(state) {
        setEditorState(state);
        props.handleChange(draftToMarkdown(convertToRaw(state.getCurrentContent())));
    }

    return <Editor editorState={editorState} onChange={handleChange} ref={editorRef}/>
}

@viperfx
Copy link

viperfx commented Aug 10, 2020

We are only doing client side rendering and getting this issue. Is there a fix?

@hallee9000
Copy link

hallee9000 commented Sep 27, 2020

Got the same error and warning but I'm using 0.11.7.
Only rendered in client and customize some element in editor.

UPDATE
Seems like adding userSelect="none" and contentEditable={false} to custom element can fix it.

Sep-27-2020 17-12-58

@wimsikal
Copy link

wimsikal commented Dec 5, 2020

Thank you. For me this worked with next.js

import React, { Component } from 'react'
import { Editor, EditorState } from 'draft-js'
class App extends Component {
    constructor(props) {
        super(props)
        this.state = {
            editorState: EditorState.createEmpty()
        }
    }


    onChange(editorState) {
        this.setState({
            editorState: editorState
        })
    }

    render() {
        return (
            <div className="blog-editor">
                <Editor editorState={this.state.editorState} onChange={this.onChange.bind(this)} userSelect="none" contentEditable={false} />
            </div>
        )
    }
}
export default App

@phattranky
Copy link

phattranky commented Jan 16, 2021

Follow the workaround in this Example will solve this issue

https://github.com/facebook/draft-js/blob/master/examples/draft-0-10-0/universal/editor.js

Just simply create an empty content instead to use the function createEmpty

Here is my component is working with the react-hook-form

import React, { useEffect } from "react";
import { Editor, EditorState, ContentState, convertFromRaw } from "draft-js";
import "draft-js/dist/Draft.css";

export { EditorState, ContentState };

interface PropTypes {
  name?: string;
  value?: string;
  onChange?: Function;
}

// Trick to fix issue with NextJS https://github.com/facebook/draft-js/blob/master/examples/draft-0-10-0/universal/editor.js
const emptyContentState = convertFromRaw({
  entityMap: {},
  blocks: [
    {
      text: "",
      key: "foo",
      type: "unstyled",
      entityRanges: [],
    },
  ],
});

function RichTextEditor({ name, value, onChange }: PropTypes) {
  const [editorState, setEditorState] = React.useState(
    EditorState.createWithContent(emptyContentState)
  );

  useEffect(() => {
    setEditorState(
      EditorState.createWithContent(ContentState.createFromText(value))
    );
  }, []);

  return (
    <Editor
      editorKey={name}
      editorState={editorState}
      onChange={(editorState) => {
        setEditorState(editorState);

        onChange(editorState.getCurrentContent().getPlainText());
      }}
      userSelect="none"
      contentEditable={false}
    />
  );
}

export default RichTextEditor;

<Controller
        as={RichTextEditor}
        name="description"
        control={control}
        defaultValue=""
      />

@washington299
Copy link

Follow the workaround in this Example will solve this issue

https://github.com/facebook/draft-js/blob/master/examples/draft-0-10-0/universal/editor.js

Just simply create an empty content instead to use the function createEmpty

Here is my component is working with the react-hook-form

import React, { useEffect } from "react";
import { Editor, EditorState, ContentState, convertFromRaw } from "draft-js";
import "draft-js/dist/Draft.css";

export { EditorState, ContentState };

interface PropTypes {
  name?: string;
  value?: string;
  onChange?: Function;
}

// Trick to fix issue with NextJS https://github.com/facebook/draft-js/blob/master/examples/draft-0-10-0/universal/editor.js
const emptyContentState = convertFromRaw({
  entityMap: {},
  blocks: [
    {
      text: "",
      key: "foo",
      type: "unstyled",
      entityRanges: [],
    },
  ],
});

function RichTextEditor({ name, value, onChange }: PropTypes) {
  const [editorState, setEditorState] = React.useState(
    EditorState.createWithContent(emptyContentState)
  );

  useEffect(() => {
    setEditorState(
      EditorState.createWithContent(ContentState.createFromText(value))
    );
  }, []);

  return (
    <Editor
      editorKey={name}
      editorState={editorState}
      onChange={(editorState) => {
        setEditorState(editorState);

        onChange(editorState.getCurrentContent().getPlainText());
      }}
      userSelect="none"
      contentEditable={false}
    />
  );
}

export default RichTextEditor;
<Controller
        as={RichTextEditor}
        name="description"
        control={control}
        defaultValue=""
      />

thank you very much my friend, i spent a lot of time looking for this solution.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

10 participants