这是我的博客组件
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]);
但这会将页面呈现为无穷大。但有效。 我正在寻找一种解决方案,仅在状态更改时进行渲染,而不会进入无限循环..
我会建议类似的事情:
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