sdemlong
sdemlong

Reputation: 3

React form component does not update with Tiny MCE

The "content" field of this form no longer updates when I try to implement the TinyMCE wysiwyg. I know that my handleUpdate function is a bit different than the TinyMCE documentation on how to handle React components, but to my knowledge, it should function the same way. Does anybody know why this integration is not working?

import { useState } from 'react';
import { Editor } from "@tinymce/tinymce-react";
import "./NewBlogPost.css";

function NewBlogPost(props) {
  const [formData, setFormData] = useState({
    title: '',
    content: '',
    image_url: ''
  })

  const handleChange = (e) => {
    const { name, value } = e.target;
    setFormData(prevState => ({
      ...prevState,
      [name]: value
    }))
  }

  const saveBlog = (e) => {
    e.preventDefault();
    props.handleCreate({
      ...formData
    })
  }

  const clearForm = (e) => {
    e.preventDefault();
    setFormData({
      title: '',
      content: '',
      image_url: ''
    })
  }

  return (
    <div>
      <h1>Create New Blog Post</h1>
      <form
        className="new-blog-form"
        onSubmit={saveBlog}>
        <div>
        <label className="form-label">Title:
          <input
            className="form-input"
            type='text'
            name='title'
            value={formData.title}
            onChange={handleChange}
          />
        </label>
        </div>
        <div>
        <label className="form-label">Image URL:
          <input
            className="form-input"
            type='text'
            name='image_url'
            value={formData.image_url}
            onChange={handleChange}
          />
        </label>
        </div>
        <div>
          <label> Content:
            <Editor
              textareaName="text-area"
              name='content'
              value={formData.content}
              outputFormat= 'text'
              init={{
                height: 500,
                width: 420,
                menubar: false,
                toolbar: 'undo redo | formatselect | bold italic underline | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | help'
              }}
              onChange={handleChange}
            />
          </label>
        </div>
        <div>
        <button className="button" id="save-button">Save</button>
        <button
          className="button"
          id="clear-button"
          onClick={clearForm}
        >Clear</button>
        </div>
      </form>
    </div>
  );
}

export default NewBlogPost; 

Upvotes: 0

Views: 1553

Answers (1)

jean182
jean182

Reputation: 3515

You need to do a few changes to adapt the tinymce editor in your code and still keep your handleChange function reusable, you are making a controlled form so first you need to add a function that is going to build what the handleChange needs to work:

const parseEditorData = (content, editor) => {
 //content is the current value of the text editor
 // editor is an object that holds the html element that in this case is the text area where the name prop will be stored.
 const { targetElm } = editor;
 // This name value references the prop that you pass as textAreaName (content in your case)
 const { name } = targetElm;

 // This function returns an object that your handle change can parse correctly
 return {
  target: {
    name,
    value: content
  }
 };
};

Now that you have that parse function ready you need to slightly change the props in your Editor component:

  <Editor
    outputFormat='text'
    init={{
     height: 500,
     width: 420,
     menubar: false,
     toolbar: 'undo redo | formatselect | bold italic underline | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | help'
    }}
    onEditorChange={(content, editor) =>
      handleChange(parseEditorData(content, editor))
    }
    value={formData.content}
    textareaName="content"
  />

As you can see the onEditorChange will run the handleChange with the parsed object received from the parseEditorData function, this result will look like the one you need to properly run the handleChange. Last but not leas the textAreaName prop will be the one that you need to pass to hold the reference of the content key in the formData object.

Please check this sandbox that illustrates the process: https://codesandbox.io/s/still-river-2q6pf?file=/src/App.js:840-862

Upvotes: 1

Related Questions