为什么我删除了一个post还要刷新页面? MERN堆栈

Why do I have to refresh the page when I delete a post? MERN stack

我是MERN堆栈的初学者,我很感兴趣为什么删除文档后必须刷新页面(post)?

这是我的Action.js

export const deletePost = id => async (dispatch, getState) => {
  try {
    dispatch({ type: DELETE_POST_BEGIN });

    const {
      userLogin: { userInfo },
    } = getState();

    const config = {
      headers: {
        Authorization: `Bearer ${userInfo.token}`,
      },
    };

    const { data } = await axios.delete(`/api/v1/post/${id}`, config);

    dispatch({ type: DELETE_POST_SUCCESS, payload: data });
  } catch (error) {
    dispatch({
      type: DELETE_POST_FAIL,
      payload: { msg: error.response.data.msg },
    });
  }
};

这是我的Reducer.js

export const deletePostReducer = (state = {}, action) => {
  switch (action.type) {
    case DELETE_POST_BEGIN:
      return { loading: true };
    case DELETE_POST_SUCCESS:
      return { loading: false };
    case DELETE_POST_FAIL:
      return { loading: false, error: action.payload.msg };
    default:
      return state;
  }
};

这是我的主页,我在其中列出了所有 post:

import { useEffect } from 'react';
import { Col, Container, Row } from 'react-bootstrap';
import { useDispatch, useSelector } from 'react-redux';
import { getPosts } from '../actions/postActions';
import Loader from '../components/Loader';
import Message from '../components/Message';
import Post from '../components/Post';

const HomePage = () => {
  const dispatch = useDispatch();

  const allPosts = useSelector(state => state.getPosts);
  const { loading, error, posts } = allPosts;

  const deletePost = useSelector(state => state.deletePost);
  const { loading: loadingDelete } = deletePost;

  useEffect(() => {
    dispatch(getPosts());
  }, [dispatch]);

  return (
    <Container>
      {loading || loadingDelete ? (
        <Loader />
      ) : error ? (
        <Message variant='danger'>{error}</Message>
      ) : (
        <>
          <Row>
            {posts.map(post => (
              <Col lg={4} key={post._id} className='mb-3'>
                <Post post={post} />
              </Col>
            ))}
          </Row>
        </>
      )}
    </Container>
  );
};

export default HomePage;

这是我的单个 Post 组件:

const Post = ({ post }) => {
  const dispatch = useDispatch();

  const allPosts = useSelector(state => state.getPosts);
  const { loading, error, posts } = allPosts;

  const userLogin = useSelector(state => state.userLogin);
  const { userInfo } = userLogin;

  const handleDelete = id => {
    dispatch(deletePost(id));
  };

  return (
    <>
      <div>{post.author.username}</div>
      <Card>
        <Card.Img variant='top' />
        <Card.Body>
          <Card.Title>{post.title}</Card.Title>
          <Card.Text>{post.content}</Card.Text>
          <Button variant='primary'>Read more</Button>
          {userInfo?.user._id == post.author._id && (
            <Button variant='danger' onClick={() => handleDelete(post._id)}>
              Delete
            </Button>
          )}
        </Card.Body>
      </Card>
    </>
  );
};

还有我的控制器:

const deletePost = async (req, res) => {
  const postId = req.params.id;
  const post = await Post.findOne({ _id: postId });

  if (!post.author.equals(req.user.userId)) {
    throw new BadRequestError('You have no permission to do that');
  }

  await Post.deleteOne(post);

  res.status(StatusCodes.NO_CONTENT).json({
    post,
  });
};

我希望有人能帮我解决这个问题,这当然很简单,但我是初学者,我正在努力理解。

我认为问题是您在删除成功后没有获取帖子。

HomePage 组件中试试这个:

...
const [isDeleting, setIsDeleting] = useState(false);
const { loading: loadingDelete, error: deleteError } = deletePost;

useEffect(() => {
    dispatch(getPosts());
}, [dispatch]);

useEffect(() => {
    if (!deleteError && isDeleting && !loadingDelete) {
        dispatch(getPosts());
    }
    setIsDeleting(loadingDelete);        
}, [dispatch, deleteError, isDeleting, loadingDelete]);
...

另一种方法是使用“过滤”,但您必须这样更新您的减速器:

export const deletePostReducer = (state = {}, action) => {
  switch (action.type) {
    case DELETE_POST_BEGIN:
      return { loading: true };
    case DELETE_POST_SUCCESS:
      return { loading: false, data: action.payload}; // <-- this was changed
    case DELETE_POST_FAIL:
      return { loading: false, error: action.payload.msg };
    default:
      return state;
  }
};

现在在您的 HomePage 组件中,您将在渲染时执行如下操作:

...
const { loading: loadingDelete, data: deletedPost } = deletePost;
...
useEffect(() => {
  dispatch(getPosts());
  if (deletedPost) {
    console.log(deletedPost);
  }
}, [dispatch, deletedPost]);
  
return (
   ...
   <Row>
     {posts.filter(post => post._id !== deletedPost?._id).map(post => (
        <Col lg={4} key={post._id} className='mb-3'>
           <Post post={post} />
        </Col>
     ))}
   </Row>
)