0

I have a form and I replaced the textarea with ReactQuill based on this tutorial (https://www.youtube.com/watch?v=DjEANvaZFv0&feature=youtu.be) to get Rich Text. However once I did it, I got an error saying 'Error: React.Children.only expected to receive a single React element child' (see screenshot below).

This only came up after I replaced the textarea with ReactQuill but on the error page it shows me the code in the App.js where I've implemented google authentication with firebase and I'm not sure how the two are connected. How do I fix this?

Error page

Here's my AddArticle.js where the form is:

import React, { Component } from "react";
import firebase from "../Firebase";
import ReactQuill from "react-quill";
import "react-quill/dist/quill.snow.css";
import renderHTML from 'react-render-html';

class AddArticle extends Component {
  constructor() {
    super();
    this.ref = firebase.firestore().collection("articles");
    this.state = {
      title: "",
      content: "",
    };
  }
  onChange = (e) => {
    const state = this.state;
    state[e.target.name] = e.target.value;
    this.setState(state);
  };

  onBodyChange(e) {
    this.setState({ content: e });
  }

  onSubmit = (e) => {
    e.preventDefault();

    const { title, content } = this.state;

    this.ref
      .add({
        title,
        content,
      })
      .then((docRef) => {
        this.setState({
          title: "",
          content: "",
        });
        this.props.history.push("/");
      })
      .catch((error) => {
        console.error("Error adding document: ", error);
      });
  };

  render() {
    const { title, content } = this.state;
    return (
      <div className="container">
        <br></br>
        <br></br>
        <br></br>
        <div className="panel panel-default">
          <div className="panel-heading">
            <h3 className="panel-title text-center">Create a new article</h3>
          </div>
          <br></br>
          <br></br>
          <div className="panel-body">
            <form onSubmit={this.onSubmit}>
              <div className="form-group input-group-lg">
                <label for="title">Title:</label>
                <input
                  type="text"
                  className="form-control"
                  name="title"
                  value={title}
                  onChange={this.onChange}
                  placeholder="Title"
                />
              </div>
              <div className="form-group">
                <label for="content">Content:</label>
                <ReactQuill
                  modules={AddArticle.modules}
                  formats={AddArticle.formats}
                  name="content"
                  onChange={this.onBodyChange}
                  placeholder="Content"
                  cols="80"
                  rows="20"
                >
                  {content}
                </ReactQuill>
              </div>
              <button type="submit" className="btn btn-success">
                Submit
              </button>
            </form>
          </div>
        </div>
      </div>
    );
  }
}

// Quill Config
AddArticle.modules = {
  toolbar: [
    [{ header: [1, 2, 3, 4, 5, 6, false] }],
    [{ size: [] }],
    ["bold", "italic", "underline", "strike", "blockquote"],
    [
      { list: "ordered" },
      { list: "bullet" },
      { indent: "-1" },
      { indent: "+1" },
    ],
    ["link", "image", "video"],
    ["clean"],
    ["code-block"],
  ],
  clipboard: {
    // toggle to add extra line breaks when pasting HTML:
    matchVisual: false,
  },
};

AddArticle.formats = [
  "header",
  "font",
  "size",
  "bold",
  "italic",
  "underline",
  "strike",
  "blockquote",
  "list",
  "bullet",
  "indent",
  "link",
  "image",
  "video",
  "code-block",
];

export default AddArticle;

And here is my App.js in case it's relevant:

import React, { Component } from "react";
import "./App.css";
import Navbar from "./components/Navbar";
import Main from "./Main";
import firebase from "firebase";
import StyledFirebaseAuth from "react-firebaseui/StyledFirebaseAuth";


class App extends Component {
  state={isSignedIn:false}
  uiConfig = {
    signInFlow: "popup",
    signInOptions: [
      firebase.auth.GoogleAuthProvider.PROVIDER_ID
    ],
    callbacks: {
      signInSuccess: () => false
    }
  }

  componentDidMount = () => {
    firebase.auth().onAuthStateChanged(user => {
      this.setState({isSignedIn:!!user})
    })
  }

  render() {
    return (
      <div>
        {this.state.isSignedIn ? (
          <span>
            <Navbar />
            <Main />
          </span>
        ) :
        (
          <StyledFirebaseAuth
            uiConfig={this.uiConfig}
            firebaseAuth={firebase.auth()}
            />
        )}
      </div>
    );
  }
}

export default App;
cldev
  • 671
  • 8
  • 18

1 Answers1

1

As described here, I suggest passing content as ReactQuill's value instead of making it a child:

<ReactQuill
    value={this.state.content}
    // ... other props are OK
/> // Close the tag: no children
Louis Coulet
  • 3,663
  • 1
  • 21
  • 39
  • Thanks! I now have to deal with different types of error but you were right about this! If you can have a look at the new error I would appreciate it --> https://ibb.co/px3SSCs – cldev Sep 17 '20 at 13:46
  • I am glad it helped. For your new error, I see two issues: first you should not mutate state as you are doing, second, e.target.name looks correct to me, something else is at play. I suggest you use the console to find out, happy coding! – Louis Coulet Sep 17 '20 at 14:03
  • this.setState( { [e.target.name]: e.target.value } ) – Louis Coulet Sep 17 '20 at 14:04
  • I'm still getting the same error but it's fine, I'll keep trying. Thanks so much for all the direction! – cldev Sep 17 '20 at 14:32