如何在另一个组件上的deleteHandler之后渲染一个组件

问题描述 投票:0回答:1

这是我的博客组件

import { useEffect, useState } from "react";
import { Link } from "react-router-dom";
import { useAuthContext } from "../../hooks/useAuthContext";
import BlogPost from "../../components/Blog/BlogPost";
import * as blogService from "../../services/blogService";

import "./Blog.css";

export default function Blog() {
  const [posts, setPosts] = useState([]);
  const { user } = useAuthContext();
  

  // useEffect(() => {
  //   const fetchData = async () => {
  //     const result = await blogService.getAll();
  //     setPosts(result);
  //   };

  //   fetchData();
  // }, [posts]);

  useEffect(() => {
    blogService.getAll().then((result) => setPosts(result));
  }, []);

  return (
    <>
   
      <div className="page-nav">
        <div className="container">
          <div className="row">
            <h2 className="text-start">Our Blogs Posts</h2>
            <ul>
              {user && (
                <li className="button-add-li">
                  <Link to="/blog/create">
                    <i className="button-add-post"> Add Blog post</i>
                  </Link>
                </li>
              )}
            </ul>
          </div>
        </div>
      </div>

      <div id="blog-page" className="blog-page">
        <div className="container-page">
          <div className="row-blog">
            {posts.map((post) => {
              let keys = Object.keys(post).join("");
              let data = Object.values(post);
              
              return <BlogPost key={keys} id={keys} {...data[0]} />;
            })}
          </div>
        </div>
      </div>
        
    </>
  );
}

这是详细信息组件,其中是我的 onDeleteHandler,我在其中删除一篇文章。

/* eslint-disable no-unused-vars */
/* eslint-disable react/prop-types */
import { useEffect, useState } from "react";
import { redirect, useParams } from "react-router-dom";
import { Link } from "react-router-dom";
import { useNavigate } from "react-router-dom";

import { useAuthContext } from "../../hooks/useAuthContext";

import * as blogService from "../../services/blogService";
import * as commentsService from "../../services/commentsService";

import "./BlogDetails.css";

const formInitialState = {
  username: "",
  comment: "",
};

export default function BlogDetails() {
  const [post, setPost] = useState({});
  const { postId } = useParams();
  const [comments, setComments] = useState([]);
  const [runComment, setRunComment] = useState(0);

  const [formValues, setFormValues] = useState(formInitialState);

  const navigate = useNavigate();

  const { user } = useAuthContext();

  useEffect(() => {
    blogService.getOne(postId).then(setPost);

    commentsService.getAll(postId).then(setComments);
  }, [postId]);

  useEffect(() => {
    commentsService.getAll(postId).then(setComments);
    setRunComment(0);
  }, [runComment]);

  // useEffect(() => {
  //   blogService.getOne(postId).then(setPost);
  // }, [post]);

  const addCommentHandler = async (e) => {
    e.preventDefault();

    const newComment = await commentsService.create(
      postId,
      user.email,
      formValues.comment
    );

    setComments((prevComments) => [...prevComments, newComment]);
    setRunComment(1);

    setFormValues(formInitialState);
  };

  const changeHandler = (e) => {
    setFormValues((state) => ({
      ...state,
      [e.target.name]: e.target.value,
    }));
  };

  const onDeleteHandler = async () => {
    alert("Are you sure you want to delete this post?");
    const response = await blogService.deleteOne(postId);
    if(response) {
      navigate('/blog');
    }
  };

  return (
    <>
      <div className="page-nav details">
        <div className="container">
          <div className="row">
            <h2 className="text-start">DETAILS</h2>
            <ul className="nav-links">
              <li>
                <Link to="/">Home</Link>
              </li>
              <li>
                <Link to="/blog">Blog</Link>
              </li>
              <li> {post.title}</li>
            </ul>
          </div>
        </div>
      </div>

      <div className="details-page">
        <div className="container">
          <div className="post-details">
            <div className="post-img">
              <img src={post.imageUrl} alt="" />
            </div>
            <div className="post-info">
              <h2>{post.title}</h2>
              <p>{post.description}</p>
              <div className="creator-info">
                <p>Created at: {post.date}</p>
                <p>By: {post.creator}</p>
              </div>
            </div>
          </div>
          {user &&
            (user.email === post.creator || user.email === "[email protected]") && (
              <div className="details-buttons">
                <button className="edit-btn">
                  <Link className="userline-none" to={`/blog/${postId}/edit`}>
                    Edit
                  </Link>
                </button>

                <button className="delete-btn" onClick={onDeleteHandler}>
                  <Link className="userline-none" to="/blog">
                    Delete
                  </Link>
                </button>
              </div>
            )}
        </div>
      </div>

      <div className="details-comments">
        <div className="container">
          <h2>Comments:</h2>
          <ul className="comment-ul">
            {comments.map(({ _id, username, text }) => (
              <li key={_id} className="comment">
                <div className="comment-text">
                  <p>
                    <strong>{username}:</strong>
                  </p>
                  <p className="empty-line"></p>
                  <p>
                    <i>{text}</i>
                  </p>
                </div>
              </li>
            ))}
          </ul>

          {comments.length === 0 && <p className="no-comment">No comments.</p>}

          {user && (
            <article className="create-comment">
              <label>Add new comment:</label>
              <form className="form" onSubmit={addCommentHandler}>
                <br />
                <input
                  name="comment"
                  value={formValues.comment}
                  onChange={changeHandler}
                  placeholder="Comment......"
                ></input>{" "}
                <br />
                <input
                  className="btn-submit"
                  type="submit"
                  value="Add Comment"
                />
              </form>
            </article>
          )}
        </div>
      </div>
    </>
  );
}

当我在删除项目后导航到 /blog 时 - /Blog 组件不会呈现(已删除的项目仍在页面上)。如果我在浏览器上按 F5,已删除的项目就会消失。

我试试这个:

export default function Blog() {
  const [posts, setPosts] = useState([]);
  const { user } = useAuthContext();
  

  // useEffect(() => {
  //   const fetchData = async () => {
  //     const result = await blogService.getAll();
  //     setPosts(result);
  //   };

  //   fetchData();
  // }, [posts]);

  useEffect(() => {
    blogService.getAll().then((result) => setPosts(result));
  }, [posts]);

但这会将页面呈现为无穷大。但有效。 我正在寻找一种解决方案,仅在状态更改时进行渲染,而不会进入无限循环..

reactjs infinite-loop renderer
1个回答
0
投票

我会建议类似的事情:

  const [postsRefreshKey, setPostsRefreshKey] = useState(0);
  useEffect(() => {
    blogService.getOne(postId).then(setPost);
  }, [postId, postsRefreshKey]);

...

  const onDeleteHandler = async () => {
    alert("Are you sure you want to delete this post?");
    const response = await blogService.deleteOne(postId);
    postsRefreshKey(prev=>prev+1);
  };

但最好的选择是使用 React Query:https://tanstack.com/query/v5/docs/react/overview

© www.soinside.com 2019 - 2024. All rights reserved.