Saya mendapatkan kesalahan berikut setelah saya mengimplementasikan CKeditor saya ke Modal reaksi:

Peringatan: Tidak dapat melakukan pembaruan status Bereaksi pada komponen yang tidak dipasang. Ini adalah larangan, tetapi ini menunjukkan kebocoran memori di aplikasi Anda. Untuk memperbaikinya, batalkan semua langganan dan tugas asinkron dalam fungsi pembersihan useEffect.

CKeditor muncul pada baris 132, berikut kode implementasinya:

import { Avatar } from "@material-ui/core";
import { MoreHorizOutlined, ShareOutlined } from "@material-ui/icons";
import ArrowUpwardOutlinedIcon from "@material-ui/icons/ArrowUpwardOutlined";
import ArrowDownwardOutlinedIcon from "@material-ui/icons/ArrowDownwardOutlined";
import RepeatOutlinedIcon from "@material-ui/icons/RepeatOutlined";
import ChatBubbleOutlineOutlinedIcon from "@material-ui/icons/ChatBubbleOutlineOutlined";
import React, { useEffect, useState } from "react";
import "../style/Post.css";
import Modal from "react-modal";
import { useDispatch, useSelector } from "react-redux";
import {
  selectQuestionId,
  selectQuestionName,
  setQuestionInfo,
} from "../features/questionSlice";
import db from "../firebase";
import { selectUser } from "../features/userSlice";
import firebase from "firebase";
import ClassicEditor from "@ckeditor/ckeditor5-react";
import { CKEditor } from "@ckeditor/ckeditor5-build-classic";

Modal.setAppElement("#root");

function Post({ Id, question, imageUrl, timestamp, buildFaastUser }) {
  const user = useSelector(selectUser);
  const [openModal, setOpenModal] = useState(false);
  const dispatch = useDispatch();

  const questionId = useSelector(selectQuestionId);
  const questionName = useSelector(selectQuestionName);
  const [answer, setAnswer] = useState("");
  const [getAnswer, setGetAnswer] = useState([]);

  useEffect(() => {
    if (questionId) {
      db.collection("questions")
        .doc(questionId)
        .collection("answer")
        .orderBy("timestamp", "desc")
        .onSnapshot((snapshot) =>
          setGetAnswer(
            snapshot.docs.map((doc) => ({ id: doc.id, answers: doc.data() }))
          )
        );
    }
  }, [questionId]);

  const handleAnswer = (e) => {
    e.preventDefault();

    if (questionId) {
      db.collection("questions").doc(questionId).collection("answer").add({
        questionId: questionId,
        timestamp: firebase.firestore.FieldValue.serverTimestamp(),
        answer: answer,
        user: user,
      });

      console.log(questionId, questionName);
      setAnswer("");
      setOpenModal(false);
    }
  };

  return (
    <div
      className="post"
      onClick={() =>
        dispatch(
          setQuestionInfo({
            questionId: Id,
            questionName: question,
          })
        )
      }
    >
      <div className="post__info">
        <Avatar src={buildFaastUser.photo} />
        <h5>
          {buildFaastUser.displayName
            ? buildFaastUser.displayName
            : buildFaastUser.email}
        </h5>
        <small>{new Date(timestamp?.toDate()).toLocaleString()}</small>
      </div>
      <div className="post__body">
        <div className="post__question">
          <p>{question}</p>
          <button
            onClick={() => setOpenModal(true)}
            className="post__btnAnswer"
          >
            Answer
          </button>

          <Modal
            isOpen={openModal}
            onRequestClose={() => setOpenModal(false)}
            shouldCloseOnOverlayClick={false}
            style={{
              overlay: {
                width: 680,
                height: 550,
                backgroundColor: "transparent",
                boxShadow:
                  "box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19);",
                zIndex: "1000",
                top: "50%",
                left: "50%",
                marginTop: "-250px",
                marginLeft: "-350px",
              },
            }}
          >
            <div className="modal__question">
              <h1>{question}</h1>
              <p>
                asked by{" "}
                <span className="name">
                  {buildFaastUser.displayName
                    ? buildFaastUser.displayName
                    : buildFaastUser.email}
                </span>{" "}
                {""}
                on{" "}
                <span className="name">
                  {new Date(timestamp?.toDate()).toLocaleString()}
                </span>
              </p>
            </div>
            <div className="modal__answer">
              <CKEditor
                required
                editor={ClassicEditor}
                data={answer}
                onChange={(e, editor) => {
                  const data = editor.getData();
                  setAnswer(e.target.data);
                }}
                placeholder="Enter your answer"
                type="text"
              />
            </div>
            <div className="modal__button">
              <button className="cancel" onClick={() => setOpenModal(false)}>
                Cancel
              </button>
              <button onClick={handleAnswer} type="submit" className="add">
                Add Answer
              </button>
            </div>
          </Modal>
        </div>
        <div className="post__answer">
          {getAnswer.map(({ id, answers }) => (
            <p key={id} style={{ position: "relative", paddingBottom: "5px" }}>
              {Id === answers.questionId ? (
                <span>
                  {answers.answer}
                  <br />
                  <span
                    style={{
                      position: "absolute",
                      color: "gray",
                      fontSize: "small",
                      display: "flex",
                      right: "0px",
                    }}
                  >
                    <span style={{ color: "lightblue" }}>
                      {answers.user.displayName
                        ? answers.user.displayName
                        : answers.user.email}{" "}
                      on{" "}
                      {new Date(answers.timestamp?.toDate()).toLocaleString()}
                    </span>
                  </span>
                </span>
              ) : (
                ""
              )}
            </p>
          ))}
        </div>
        <img src={imageUrl} alt="" />
      </div>
      <div className="post__footer">
        <div className="post__footerAction">
          <ArrowUpwardOutlinedIcon />
          <ArrowDownwardOutlinedIcon />
        </div>

        <RepeatOutlinedIcon />
        <ChatBubbleOutlineOutlinedIcon />
        <div className="post__footerLeft">
          <ShareOutlined />
          <MoreHorizOutlined />
        </div>
      </div>
    </div>
  );
}

export default Post;

Saya baru bereaksi sehingga mungkin ada beberapa dasar yang saya lewatkan dalam hal implementasi. Saya pasti tahu masalahnya dengan implementasi CKeditor tetapi saya tidak yakin apa masalahnya karena ini adalah komponen yang cukup sederhana.

1
cjmc 9 Mei 2021, 19:58

1 menjawab

Jawaban Terbaik

Saya dapat menghilangkan kesalahan yang tidak di-mount dengan mengatur variabel lokal yang dipasang ke true, saya telah mengaturnya ke false pada fungsi pembersihan efek (seperti yang disarankan oleh reaksi). Kemudian saya memperbarui status jika dan hanya jika nilai itu benar, yaitu jika komponen tidak dipasang yang berarti variabel kami disetel ke salah, itu tidak akan masuk ke blok if.

Berikut kodenya:

  useEffect(() => {
    let mounted = true;
    if (questionId) {
      db.collection("questions")
        .doc(questionId)
        .collection("answer")
        .orderBy("timestamp", "desc")
        .onSnapshot((snapshot) => {
          if (mounted) {
            setGetAnswer(
              snapshot.docs.map((doc) => ({ id: doc.id, answers: doc.data() }))
            );
          }
        });
    }

    return () => (mounted = false);
  }, [questionId]);
2
cjmc 10 Mei 2021, 15:03