jpuri / react-draft-wysiwyg

A Wysiwyg editor build on top of ReactJS and DraftJS. https://jpuri.github.io/react-draft-wysiwyg
MIT License
6.4k stars 1.16k forks source link

getting a setState error when using MaterialUI tabs #913

Open bmueller-sykes opened 4 years ago

bmueller-sykes commented 4 years ago

This looks like an error that was introduced with version 1.14.3. If the WYSIWYG Editor is in a MaterialUI tab, when you switch away from the editor, you get this:

Warning: Can't call setState on a component that is not yet mounted. This is a no-op, but it might indicate a bug in your application. Instead, assign to `this.state` directly or define a `state = {};` class property with the desired state in the r component.

Here's an isolated case that produces the issue (at least in my environment):

import React, { Fragment, useState } from 'react';

import Tabs from '@material-ui/core/Tabs';
import Tab from '@material-ui/core/Tab';

import { EditorState, ContentState } from 'draft-js';
import { Editor } from 'react-draft-wysiwyg';
import htmlToDraft from 'html-to-draftjs';

const toDraft = (value: any) => {
  const draftValue = htmlToDraft(value || '');
  const { contentBlocks, entityMap } = draftValue;
  const contentState = ContentState.createFromBlockArray(
    contentBlocks,
    entityMap
  );

  return EditorState.createWithContent(contentState);
};

const Test = () => {
  const [tabIndex, setTabIndex] = useState(0);
  const [editorState, setEditorState] = useState(toDraft('Hello, world!'));

  return (
    <Fragment>
      <Tabs
        centered={true}
        indicatorColor="primary"
        onChange={(evt: any, value: number) => {
          setTabIndex(value);
        }}
        textColor="primary"
        value={tabIndex}
      >
        <Tab label="Editor" value={0} />
        <Tab label="One" value={1} />
      </Tabs>
      <div>
        {tabIndex === 0 ? (
          <div>
            <Editor
              editorState={editorState}
              onEditorStateChange={(value: any) => {
                setEditorState(value);
              }}
              toolbar={{
                inline: {
                  options: ['bold', 'italic', 'underline', 'strikethrough']
                },
                list: {
                  options: ['unordered', 'ordered']
                },
                options: ['inline', 'blockType', 'list', 'textAlign'],
                textAlign: {
                  options: ['left', 'center', 'right']
                }
              }}
            />
          </div>
        ) : null}
        {tabIndex === 1 ? <div>One</div> : null}
      </div>
    </Fragment>
  );
};

export default Test;
bmueller-sykes commented 4 years ago

FWIW, this issue still exists in 1.14.4

jpuri commented 4 years ago

@bmueller-sykes: I will check this soon.

jpuri commented 4 years ago

@bmueller-sykes : can you plz share complete trace of warning. I am not able to replicate issue and even find which code change may be causing this.

bmueller-sykes commented 4 years ago

@jpuri Hopefully this is useful. Let me know if I can provide any further detail. I'm sorry to say the error message itself is pretty vague.

Screen Shot 2020-01-13 at 10 32 13 AM
milkysingh commented 4 years ago

@jpuri any solutions to this warning yet?

MiadV commented 4 years ago

I have the same issue when using inside MUI Tab

oikantik commented 4 years ago

Same issue. As soon as I focus i.e try to type into the box, I see those errors in console log.

https://codesandbox.io/s/brave-gareth-pwrlz?file=/src/App.js

rafayetn commented 4 years ago

Did anyone find any solution to this?

megarg commented 4 years ago

I am getting this error even without material UI. Is there any solution?

bmueller-sykes commented 4 years ago

@oikantik to be clear, it doesn't actually go away on production--React just doesn't report errors in production environments, for performance and security reasons.

charlesomer commented 3 years ago

@jpuri Are you able to take a look at some of the PR which might fix this please? (#1044 & #1008) There are now a few issues around which I think relate to the same problem (#953, #951 & #918). I'd like to use this for an application but this issue is currently preventing me (and I'm sure others too). Thank you 😄

absingh927 commented 3 years ago

@jpuri any chance the PRs can be looked at, it would solve a few issues pretty quickly! 😄

nick4fake commented 3 years ago

Guys, as it looks like this repo is not maintained I've re-forked and pushed updated version (based on https://github.com/jpuri/react-draft-wysiwyg/pull/1044): https://www.npmjs.com/package/@nick4fake/react-draft-wysiwyg

Please note, that for typescript you will need to manually add definitions:

declare module '@nick4fake/react-draft-wysiwyg' {
  import * as React from 'react';
  import * as Draft from 'draft-js';

  export type SyntheticKeyboardEvent = React.KeyboardEvent<{}>;
  export type SyntheticEvent = React.SyntheticEvent<{}>;
  export type RawDraftContentState = Draft.RawDraftContentState;

  export class EditorState extends Draft.EditorState {}
  export class ContentState extends Draft.ContentState {}
  export class ContentBlock extends Draft.ContentBlock {}
  export class SelectionState extends Draft.SelectionState {}

  export interface EditorProps {
    webDriverTestID?: string;
    onChange?(contentState: RawDraftContentState): void;
    onEditorStateChange?(editorState: EditorState): void;
    onContentStateChange?(contentState: RawDraftContentState): void;
    initialContentState?: RawDraftContentState;
    defaultContentState?: RawDraftContentState;
    contentState?: RawDraftContentState;
    editorState?: EditorState;
    defaultEditorState?: EditorState;
    toolbarOnFocus?: boolean;
    spellCheck?: boolean;
    stripPastedStyles?: boolean;
    toolbar?: object;
    toolbarCustomButtons?: Array<React.ReactElement<HTMLElement>>;
    toolbarClassName?: string;
    toolbarHidden?: boolean;
    locale?: string;
    localization?: object;
    editorClassName?: string;
    wrapperClassName?: string;
    toolbarStyle?: object;
    editorStyle?: React.CSSProperties;
    wrapperStyle?: React.CSSProperties;
    uploadCallback?(file: object): Promise<object>;
    onFocus?(event: SyntheticEvent): void;
    onBlur?(event: SyntheticEvent): void;
    onTab?(event: SyntheticKeyboardEvent): void;
    mention?: object;
    hashtag?: object;
    textAlignment?: string;
    readOnly?: boolean;
    tabIndex?: number;
    placeholder?: string;
    ariaLabel?: string;
    ariaOwneeID?: string;
    ariaActiveDescendantID?: string;
    ariaAutoComplete?: string;
    ariaDescribedBy?: string;
    ariaExpanded?: string;
    ariaHasPopup?: string;
    customBlockRenderFunc?(block: ContentBlock): any;
    wrapperId?: number;
    customDecorators?: object[];
    editorRef?(ref: object): void;
    handlePastedText?(
      text: string,
      html: string,
      editorState: EditorState,
      onChange: (editorState: EditorState) => void,
    ): boolean;
    customStyleMap?: object;
  }

  export class Editor extends React.Component<EditorProps> {
    constructor(props: Readonly<EditorProps>);
    focusEditor(): void;
  }

}
bmueller-sykes commented 3 years ago

@nick4fake Any chance you can add the Typescript definitions to the @types repo? Here's the one for react-draft-wysiwyg

https://www.npmjs.com/package/@types/react-draft-wysiwyg

amarjeet987 commented 3 years ago

@nick4fake Thanks man, works like a charm.

webdobe commented 2 years ago

@nick4fake would be awesome if you created a pr instead of a fork. So the maintainer can maintain. As I doubt you will become the new maintainer.