jpuri / react-draft-wysiwyg

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

Warning: Can't call setState and TypeError: this is undefined in typescript #953

Open programateus opened 4 years ago

programateus commented 4 years ago

The following code is throwing an error when I click inside the editor: image

`import React, { Component } from "react"; import { Editor } from "react-draft-wysiwyg"; import { stateToHTML } from "draft-js-export-html"; import { EditorState } from "draft-js"; import "react-draft-wysiwyg/dist/react-draft-wysiwyg.css"; import "./style.css";

class Email extends Component { state = { editorState: EditorState.createEmpty(), };

private onEditorChange(editorState: EditorState) { this.setState({ editorState }); }

render() { const { editorState } = this.state;

return (
  <div className="align-self-stretch">
    <Editor
      editorState={editorState}
      toolbarClassName="toolbar"
      wrapperClassName="wrapper"
      editorClassName="editor"
      onEditorStateChange={this.onEditorChange}
    />
  </div>
);

} }

export default Email; `

If I comment the line this.setState({ editorState }); I dont get the error anymore, but the warning is still there. Don't know why or how this is happening, need some help.

Edit: code tag is not working

rafayetn commented 4 years ago

Did you find any solution?

programateus commented 4 years ago

Did you find any solution?

I'm not sure how I made it work, but there's the code sample:

import React from "react";
import { Editor } from "react-draft-wysiwyg";
import { EditorState } from "draft-js";
import axios from "../../../../utils/AxiosClient";
import "react-draft-wysiwyg/dist/react-draft-wysiwyg.css";
import "./style.css";

interface Props {
  editorState: EditorState;
  onEditorChange: (editorState: EditorState) => void;
  title: string;
  onChange: (event: React.ChangeEvent<HTMLInputElement>) => void;
}

const Email: React.FC<Props> = ({
  editorState,
  onEditorChange,
  title,
  onChange,
}) => {
  const onUploadFile = (file: File) => {
    return new Promise<{}>(async (resolve, reject) => {
      const data = new FormData();

      data.append("image", file);

      try {
        const res = await axios.post("https://api.imgur.com/3/image", data, {
          headers: {
            "Content-Type": "multipart/form-data",
            Authorization: "",
          },
        });

        const img = res.data.data;
        resolve({ data: { link: img.link } });
      } catch (e) {
        reject(e);
      }
    });
  };

  return (
    <div>
      <div className="row">
        <div className="col">
          <div className="form-group">
            <input
              type="text"
              name="title"
              className="form-control"
              id="title"
              placeholder="Email Title"
              value={title}
              onChange={onChange}
            />
          </div>
        </div>
      </div>
      <div className="row">
        <div className="col">
          <Editor
            toolbar={{ image: { previewImage: true } }}
            uploadCallback={onUploadFile}
            editorState={editorState}
            toolbarClassName="toolbar"
            wrapperClassName="wrapper"
            editorClassName="editor"
            onEditorStateChange={onEditorChange}
          />
        </div>
      </div>
    </div>
  );
};

export default Email;
Kseng commented 3 years ago

@mateusbds mateusbds may i know how you fix the Code tag? i got the same issue here.

Eru2008 commented 3 years ago

I have the same problem. Is there any solution?

Akeloya commented 3 years ago

This issue not related to react-draft-wysiwyg.

React.Component doesn't auto bind methods to itself. You need to bind them yourself in constructor

React: "this" is undefined React: handing events You can directly set state in jsx and there won't be any problem of 'this' undefined: <Editor toolbar={{ image: { previewImage: true } }} uploadCallback={onUploadFile} editorState={editorState} toolbarClassName="toolbar" wrapperClassName="wrapper" editorClassName="editor" onEditorStateChange={(state)=>this.setState({state})} />