admin管理员组

文章数量:1287775

everyone.

So I have a an app, where the user can create posts, if you are the owner of this post, you can click on delete button which will show a modal and you can delete the post.

I can delete the post, but now I am trying to redirect the user back to the main page or any other page, however It doesn't work.

I tried using history.push, but it is not available, window.location.replace("/") doesn't work, and I even tried using this

const navigate = useNavigate();

and in the form submit

navigate("/");

This doesn't work at all, instead what happens is:

  • The DELETE request gets send
  • The post gets deleted from the database
  • The page reloads and doesn't redirect the user
  • The console throws fetch error

The user can see that the post is deleted only after he manualy switches pages, which I don'T want, I want the user to be automaticaly redirected once he pressed the Delete post button.

This is my package.json

  "dependencies": {
    "@testing-library/jest-dom": "^5.16.4",
    "@testing-library/react": "^13.3.0",
    "@testing-library/user-event": "^13.5.0",
    "@types/jest": "^27.5.2",
    "@types/node": "^16.11.41",
    "@types/react": "^18.0.14",
    "@types/react-dom": "^18.0.5",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-router-dom": "^6.3.0",
    "react-scripts": "5.0.1",
    "typescript": "^4.7.4",
    "web-vitals": "^2.1.4"
  },

And this is my code for form submit and delete on the Post

const Post_page = () => {

  const auth = useContext(context_auth);
  
  const { isLoading, error, sendRequest, clearError } = useHttpRequest();
  const [showModal, setShowModal] = useState(false);
  const userID = useParams().id;

  const [title, setTitle] = useState();
  const [postID, setPostId] = useState();
  const [description, setDescription] = useState();
  const [creator_name, setCreatorName] = useState();
  const [creationTime, setCreationTime] = useState('');

  const openModal = (event: any) =>  {
      setShowModal(true);
  }
  const closeModal = (event: any) =>  {
      setShowModal(false);
  }
  const onSubmit = async (event: any) => {
    event.preventDefault();
    console.log("aaaaaaaaaaaaa");
    try {
      const url: string = `http://localhost:8000/api/posts/${postID}`;
      await sendRequest(url, 'DELETE');
      window.location.replace("/");
      closeModal(event);

    } catch (err: any) {
      console.log(err.message)
    }
    
   
    
  }

  useEffect(() => {
    const fetchPosts = async () => {
      try {

        const url: string = `http://localhost:8000/api/posts/${userID}`;
        const responseData = await sendRequest(url);

       console.log(responseData.post);
       const data = responseData.post;

       setTitle(data.title);
       setDescription(data.description);
       setPostId(data.id);
       const timeOfCreation = new Date(data.createdAt).toDateString();
       setCreationTime(timeOfCreation);
       setCreatorName(data.creator_name);

      } catch (err) { }}

      fetchPosts();
  }, [sendRequest]);


  return (
    <>
    {isLoading &&
      <h1>Loading ...</h1>
    }
    { !isLoading && showModal &&  auth.isLoggedIn &&   
      <Modal title='Delete post' show={showModal} onCancel={closeModal}>
        <>
        <Form onSubmit={onSubmit} classname='modal_content_height_auto'>
            <p className='post_description'>Do you want to delete this post ?</p>
            <Button 
                classname='button_submit' 
                classname_enabled='button_submit_enabled' 
                classname_disabled='button_submit_disabled' 
                type='submit'
                label='Delete' 
      
              />
          </Form>
        </>
        

      </Modal>
    }

    { !isLoading &&
    
     <here is the post stuff, hidden as its not important>
      <Comments />
      </div>
    }
    </>
  )
}

export default Post_page

EDIT: Posting backend code for post DELETE

this is my route

route.delete('/:postID', deletePost)

and this is the deletePost handler

export const deletePost = async (req: Request, res: Response, next: NextFunction) => {
    const postID = req.params.postID;
    let post: any;

    try {
        post = await POST.findById(postID).populate('creator_id');
    } catch (err: any) {
        console.log(err.message)
        const error = {
            message: "Couldn't delete POST !",
            code: 500
        };
    
        return next(error);
    }

    if(!post){
        const error = {
            message: "Post doesn't exist, so it could not be deleted !",
            code: 404
        };
    
        return next(error);
    }

    try{
       await post.remove();
       post.creator.posts.pull(post);
       await post.creator.save();
       
    }catch(err){
        const error = {
            message: "Couldn't delete POST from DATABASE!",
            code: 500
        };
    
        return next(error);
    }
    res.status(200).json({message: "Post deleted !"});
}

EDIT: ADDED SCHEMA FOR POST AND USER This is my Schema for Post which is also connected to User Schema

import mongoose from "mongoose";

const Schema = mongoose.Schema;

const post_Schema = new Schema({
        title: { type: String, required: true, },
        description: { type: String, required: true, },
        imageURL: { type: String },
        creator_id: { type: mongoose.Types.ObjectId, required: true, ref: 'User'  }, //relation bewtean post and user
        creator_name: { type: String, required: true, ref: 'User'  }, //relation bewtean post and user
    },
    { timestamps: true }
    );

export const POST: mongoose.Model<any> = mongoose.model("Post", post_Schema);

and this is my User Schema

import mongoose from "mongoose";
import mongooseUniqueValidator from "mongoose-unique-validator";

const Schema = mongoose.Schema;
const validator = mongooseUniqueValidator;

const user_Schema = new Schema({
        username: { type: String, required: true, unique: true },
        email: { type: String, required: true, unique: true },
        password: { type: String, required: true, minlength: 3 },
        user_image: { type: String },
        posts: [{ type: mongoose.Types.ObjectId, required: true, ref: 'Post'  }], //relation bewtean post and user

    },{ timestamps: true }
    );

user_Schema.plugin(validator);


export const USER: mongoose.Model<any> = mongoose.model("User", user_Schema);

everyone.

So I have a an app, where the user can create posts, if you are the owner of this post, you can click on delete button which will show a modal and you can delete the post.

I can delete the post, but now I am trying to redirect the user back to the main page or any other page, however It doesn't work.

I tried using history.push, but it is not available, window.location.replace("/") doesn't work, and I even tried using this

const navigate = useNavigate();

and in the form submit

navigate("/");

This doesn't work at all, instead what happens is:

  • The DELETE request gets send
  • The post gets deleted from the database
  • The page reloads and doesn't redirect the user
  • The console throws fetch error

The user can see that the post is deleted only after he manualy switches pages, which I don'T want, I want the user to be automaticaly redirected once he pressed the Delete post button.

This is my package.json

  "dependencies": {
    "@testing-library/jest-dom": "^5.16.4",
    "@testing-library/react": "^13.3.0",
    "@testing-library/user-event": "^13.5.0",
    "@types/jest": "^27.5.2",
    "@types/node": "^16.11.41",
    "@types/react": "^18.0.14",
    "@types/react-dom": "^18.0.5",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-router-dom": "^6.3.0",
    "react-scripts": "5.0.1",
    "typescript": "^4.7.4",
    "web-vitals": "^2.1.4"
  },

And this is my code for form submit and delete on the Post

const Post_page = () => {

  const auth = useContext(context_auth);
  
  const { isLoading, error, sendRequest, clearError } = useHttpRequest();
  const [showModal, setShowModal] = useState(false);
  const userID = useParams().id;

  const [title, setTitle] = useState();
  const [postID, setPostId] = useState();
  const [description, setDescription] = useState();
  const [creator_name, setCreatorName] = useState();
  const [creationTime, setCreationTime] = useState('');

  const openModal = (event: any) =>  {
      setShowModal(true);
  }
  const closeModal = (event: any) =>  {
      setShowModal(false);
  }
  const onSubmit = async (event: any) => {
    event.preventDefault();
    console.log("aaaaaaaaaaaaa");
    try {
      const url: string = `http://localhost:8000/api/posts/${postID}`;
      await sendRequest(url, 'DELETE');
      window.location.replace("/");
      closeModal(event);

    } catch (err: any) {
      console.log(err.message)
    }
    
   
    
  }

  useEffect(() => {
    const fetchPosts = async () => {
      try {

        const url: string = `http://localhost:8000/api/posts/${userID}`;
        const responseData = await sendRequest(url);

       console.log(responseData.post);
       const data = responseData.post;

       setTitle(data.title);
       setDescription(data.description);
       setPostId(data.id);
       const timeOfCreation = new Date(data.createdAt).toDateString();
       setCreationTime(timeOfCreation);
       setCreatorName(data.creator_name);

      } catch (err) { }}

      fetchPosts();
  }, [sendRequest]);


  return (
    <>
    {isLoading &&
      <h1>Loading ...</h1>
    }
    { !isLoading && showModal &&  auth.isLoggedIn &&   
      <Modal title='Delete post' show={showModal} onCancel={closeModal}>
        <>
        <Form onSubmit={onSubmit} classname='modal_content_height_auto'>
            <p className='post_description'>Do you want to delete this post ?</p>
            <Button 
                classname='button_submit' 
                classname_enabled='button_submit_enabled' 
                classname_disabled='button_submit_disabled' 
                type='submit'
                label='Delete' 
      
              />
          </Form>
        </>
        

      </Modal>
    }

    { !isLoading &&
    
     <here is the post stuff, hidden as its not important>
      <Comments />
      </div>
    }
    </>
  )
}

export default Post_page

EDIT: Posting backend code for post DELETE

this is my route

route.delete('/:postID', deletePost)

and this is the deletePost handler

export const deletePost = async (req: Request, res: Response, next: NextFunction) => {
    const postID = req.params.postID;
    let post: any;

    try {
        post = await POST.findById(postID).populate('creator_id');
    } catch (err: any) {
        console.log(err.message)
        const error = {
            message: "Couldn't delete POST !",
            code: 500
        };
    
        return next(error);
    }

    if(!post){
        const error = {
            message: "Post doesn't exist, so it could not be deleted !",
            code: 404
        };
    
        return next(error);
    }

    try{
       await post.remove();
       post.creator.posts.pull(post);
       await post.creator.save();
       
    }catch(err){
        const error = {
            message: "Couldn't delete POST from DATABASE!",
            code: 500
        };
    
        return next(error);
    }
    res.status(200).json({message: "Post deleted !"});
}

EDIT: ADDED SCHEMA FOR POST AND USER This is my Schema for Post which is also connected to User Schema

import mongoose from "mongoose";

const Schema = mongoose.Schema;

const post_Schema = new Schema({
        title: { type: String, required: true, },
        description: { type: String, required: true, },
        imageURL: { type: String },
        creator_id: { type: mongoose.Types.ObjectId, required: true, ref: 'User'  }, //relation bewtean post and user
        creator_name: { type: String, required: true, ref: 'User'  }, //relation bewtean post and user
    },
    { timestamps: true }
    );

export const POST: mongoose.Model<any> = mongoose.model("Post", post_Schema);

and this is my User Schema

import mongoose from "mongoose";
import mongooseUniqueValidator from "mongoose-unique-validator";

const Schema = mongoose.Schema;
const validator = mongooseUniqueValidator;

const user_Schema = new Schema({
        username: { type: String, required: true, unique: true },
        email: { type: String, required: true, unique: true },
        password: { type: String, required: true, minlength: 3 },
        user_image: { type: String },
        posts: [{ type: mongoose.Types.ObjectId, required: true, ref: 'Post'  }], //relation bewtean post and user

    },{ timestamps: true }
    );

user_Schema.plugin(validator);


export const USER: mongoose.Model<any> = mongoose.model("User", user_Schema);
Share Improve this question edited Jul 15, 2022 at 16:05 Drew Reese 203k17 gold badges239 silver badges270 bronze badges asked Jul 14, 2022 at 17:22 mitas1cmitas1c 3351 gold badge3 silver badges16 bronze badges 7
  • 2 Using the useNavigate hook is the correct answer. Can you share how you were trying to use it, and be more specific about what isn't working, errors, etc? – Drew Reese Commented Jul 14, 2022 at 17:29
  • I tried to use it this way, as I saw it somewhere on the internetz const navigate = useNavigate(); const onSubmit = async (event: any) => { console.log("aaaaaaaaaaaaa"); try { const url: string = http://localhost:8000/api/posts/${postID}; await sendRequest(url, 'DELETE'); closeModal(event); navigate('/'); } catch (err: any) { console.log(err.message) } } – mitas1c Commented Jul 14, 2022 at 17:32
  • 1 Are there any errors, in the console or network tab? If there aren't any thrown errors or rejected Promises the navigate function should be called. Have you tried setting a breakpoint and stepping through the code to see where it is failing for you? It seems the DELETE request or response handling is causing an error. – Drew Reese Commented Jul 14, 2022 at 17:36
  • 1 The fetchPosts doesn't do anything in its catch block, are you sure this is where the error is being logged? – Drew Reese Commented Jul 14, 2022 at 17:40
  • 1 Can you edit your post and add your mongo Schema for the post ? Maybe you are trying to access a parameter that doesn't exist ? Which may give you an errror – Filip Studený Commented Jul 15, 2022 at 7:19
 |  Show 2 more ments

3 Answers 3

Reset to default 4 +100

From what you posted, the reason you don't redirect upon post deletion is because the backend prevents it from happening.

  1. to redirect the user after he has deleted the post, if you are using React-router-dom version 6, you need to use useNavigate(), because useHistory and have been replaced by useNavigate(), so this is how you would redirect the user if he deletes something.
    const navigate = useNavigate();
    const onSubmit = async (event: any) => {
       event.preventDefault();
       try {
           const url: string = `http://localhost:8000/api/posts/${postID}`;
           await sendRequest(url, 'DELETE');
           closeModal(event);
           navigate(`/`);
           } catch (err: any) {}
    }
  1. The reason your post doesn'T redirect is because, when you send the DELETE request the backend sends back an error, but before the error happens the Post gets deleted from the database, and its happening in the second try..catch block. The error happens here ->
    post.creator.posts.pull(post);  //THIS IS WERE THE ERROR HAPPENS

The error happens because you are searching for creator in the Post Schema, but Post Schema doesn't have creator so it panics and throws an error, instead it has creator_id and creator_name, so you should replace it like this, if you are searching for user by ID

   post.creator_id.posts.pull(post);

So your code on the backend should look like this (Its totaly same expect the post.creator_id.posts.pull(post)

export const deletePost = async (req: Request, res: Response, next: NextFunction) => {
    const postID = req.params.postID;
    let post: any;

    try {
        post = await POST.findById(postID).populate('creator_id');
    } catch (err: any) {
        console.log(err.message)
        const error = {
            message: "Couldn't delete POST !",
            code: 500
        };
        return next(error);
    }

    if(!post){
        const error = {
            message: "Post doesn't exist, so it could not be deleted !",
            code: 404
        };
        return next(error);
    }
    try{
       await post.remove();
       post.creator_id.posts.pull(post);
       await post.creator_id.save();
       
    }catch(err){
        const error = {
            message: "Couldn't delete POST from DATABASE!",
            code: 500
        };
    
        return next(error);
    }
    res.status(200).json({message: "Post deleted !"});
}

You have to useNavigate only, since you are using react router v6

const Post_page = () => {

  const auth = useContext(context_auth);
  const navigate=useNavigate();
  const { isLoading, error, sendRequest, clearError } = useHttpRequest();
  const [showModal, setShowModal] = useState(false);
  const userID = useParams().id;

  const [title, setTitle] = useState();
  const [postID, setPostId] = useState();
  const [description, setDescription] = useState();
  const [creator_name, setCreatorName] = useState();
  const [creationTime, setCreationTime] = useState('');

  const openModal = () =>  {
      setShowModal(true);
  }
  const closeModal = () =>  {
      setShowModal(false);
  }
  const onSubmit = async (event: any) => {
    event.preventDefault();
    console.log("aaaaaaaaaaaaa");

    try {
      const url: string = `http://localhost:8000/api/posts/${postID}`;
      await sendRequest(url, 'DELETE');
      //window.location.replace("/");
      navigate("/");
      closeModal();

    } catch (err: any) {
      console.log(err.message)
    }
    
   
    
  }

  useEffect(() => {
    const fetchPosts = async () => {
      try {

        const url: string = `http://localhost:8000/api/posts/${userID}`;
        const responseData = await sendRequest(url);

       console.log(responseData.post);
       const data = responseData.post;

       setTitle(data.title);
       setDescription(data.description);
       setPostId(data.id);
       const timeOfCreation = new Date(data.createdAt).toDateString();
       setCreationTime(timeOfCreation);
       setCreatorName(data.creator_name);

      } catch (err) { }}

      fetchPosts();
  }, [sendRequest]);


  return (
    <>
    {isLoading &&
      <h1>Loading ...</h1>
    }
    { !isLoading && showModal &&  auth.isLoggedIn &&   
      <Modal title='Delete post' show={showModal} onCancel={closeModal}>
        <>
        <Form onSubmit={onSubmit} classname='modal_content_height_auto'>
            <p className='post_description'>Do you want to delete this post ?</p>
            <Button 
                classname='button_submit' 
                classname_enabled='button_submit_enabled' 
                classname_disabled='button_submit_disabled' 
                type='submit'
                label='Delete' 
      
              />
          </Form>
        </>
        

      </Modal>
    }

    { !isLoading &&
    
     <here is the post stuff, hidden as its not important>
      <Comments />
      </div>
    }
    </>
  )
}

export default Post_page

If you are getting a fetch error from the delete request, that means neither of window.location.replace or closeModal functions are getting invoked because catch block is executed right after the error. Make sure that you are getting the right response from that API call.

本文标签: javascriptReactJs how to redirect on form submitStack Overflow