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?
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;
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