React+TypeScript+Material-UI表单提交成功后如何实现页面重定向
解决方案
你可以根据你使用的react-router-dom版本选择对应实现方案:
方案1:React Router v5 版本
你已经导入了Redirect组件,只需要新增状态控制该组件的渲染即可:
- 新增提交成功的状态变量
- 接口请求成功后修改状态值
- 状态为
true时直接渲染Redirect组件完成跳转
修改后的完整代码如下:
import React, { useState } from "react"; import TextField from "@material-ui/core/TextField"; import { createStyles, makeStyles, Theme } from "@material-ui/core/styles"; import { Box, Button, Container, Grid, Typography } from "@material-ui/core"; import SaveIcon from "@material-ui/icons/Save"; import { TicketDTO } from "../../service/support/types"; import { postTicket } from "../../service/support"; import { useForm } from "react-hook-form"; import { Redirect } from "react-router-dom"; export default function OpenTicket(props: any) { // 新增提交成功控制状态 const [submitSuccess, setSubmitSuccess] = useState(false); const { register, handleSubmit, formState: { errors }, } = useForm<TicketDTO>(); const onSubmit = async (data: TicketDTO) => { postTicket(data) .then(({ data }) => { console.log(data.title); // 提交成功后修改状态触发重定向 setSubmitSuccess(true); }) .catch((err) => { console.log(err); }); }; const formHandler = (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); console.log(e.target); }; // 状态为真时直接返回重定向组件 if (submitSuccess) { // 替换为你需要跳转的目标路由地址 return <Redirect to="/ticket-list" /> } return ( <Container> <form onSubmit={handleSubmit(onSubmit)}> <TextField id="title" label="工单标题" {...register("title", { required: true, maxLength: 40, })} error={!!errors.title} helperText={errors.title ? "标题不能为空且长度不能超过40字符" : ""} /> <Button variant="contained" color="primary" size="small" type="submit" startIcon={<SaveIcon />} style={{marginTop: 20}} > 提交工单 </Button> </form> </Container> ); }
方案2:React Router v6 版本
v6版本移除了Redirect组件,推荐使用useNavigate hook实现重定向:
- 替换原有导入,引入
useNavigate - 在组件内部初始化navigate方法
- 接口请求成功后直接调用navigate方法完成跳转
核心修改代码如下:
// 替换原来的Redirect导入 import { useNavigate } from "react-router-dom"; export default function OpenTicket(props: any) { const navigate = useNavigate(); const { register, handleSubmit, formState: { errors }, } = useForm<TicketDTO>(); const onSubmit = async (data: TicketDTO) => { postTicket(data) .then(({ data }) => { console.log(data.title); // 提交成功直接跳转,替换为你的目标路由 navigate("/ticket-list"); // 如果需要传递参数可以用下方写法,跳转后可从useLocation hook中取出参数 // navigate("/ticket-detail", { state: { ticketId: data.id } }) }) .catch((err) => { console.log(err); }); }; // 其余渲染逻辑保持不变 }
注意事项
- 必须等待接口请求成功后再执行重定向逻辑,不要在提交按钮点击时就提前跳转
- 如果跳转目标需要展示刚提交的工单信息,可以通过路由状态传递工单ID等参数,无需额外存本地存储
内容的提问来源于stack exchange,提问作者Peter Penzov
相关产品推荐
相关产品推荐

