繁体   English   中英

React.Js 如何重定向表单提交?

[英]React.Js how to redirect on form submit?

每个人。

所以我有一个应用程序,用户可以在其中创建帖子,如果您是该帖子的所有者,您可以单击删除按钮,该按钮将显示一个模式,您可以删除该帖子。

我可以删除帖子,但现在我试图将用户重定向回主页或任何其他页面,但是它不起作用。

我尝试使用history.push,但它不可用,window.location.replace("/") 不起作用,我什至尝试使用它

const navigate = useNavigate();

并在表单中提交

navigate("/");

这根本不起作用,而是发生的是:

  • DELETE 请求被发送
  • 帖子从数据库中删除
  • 页面重新加载并且不重定向用户
  • 控制台抛出 fetch 错误

用户只能在手动切换页面后才能看到帖子被删除,这是我不想要的,我希望用户在按下删除帖子按钮后自动重定向。

这是我的 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"
  },

这是我在帖子上提交和删除表单的代码

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

编辑:发布删除后的后端代码

这是我的路线

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

这是 deletePost 处理程序

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 !"});
}

编辑:为帖子和用户添加模式这是我的帖子模式,它也连接到用户模式

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);

这是我的用户模式

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);

您必须仅使用导航,因为您使用的是反应路由器 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

如果您从删除请求中收到 fetch 错误,这意味着window.location.replacecloseModal函数都不会被调用,因为 catch 块是在错误之后立即执行的。 确保您从该 API 调用中获得正确的响应。

根据您发布的内容,您在删除帖子时不重定向的原因是因为后端阻止了它的发生。

  1. 在用户删除帖子后重定向用户,如果您使用的是React-router-dom 版本 6 ,则需要使用useNavigate() ,因为 useHistory 已被 useNavigate() 替换,所以这就是您将如何重定向用户如果他删除了某些东西。
    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. 您的帖子没有重定向的原因是,当您发送 DELETE 请求时,后端会发回一个错误,但在错误发生之前,帖子会从数据库中删除,并且它发生在第二个 try..catch 块中。 错误发生在这里->
    post.creator.posts.pull(post);  //THIS IS WERE THE ERROR HAPPENS

发生错误是因为您在Post Schema中搜索 creator ,但 Post Schema 没有creator所以它会恐慌并抛出错误,而是它有creator_idcreator_name ,所以如果你正在搜索,你应该像这样替换它用户 ID

   post.creator_id.posts.pull(post);

所以你在后端的代码应该是这样的(它完全一样期望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 !"});
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM