React中执行fetch PUT后如何阻止页面重定向?
问题解决方法
核心原因
按钮在<form>标签内默认是submit类型,点击后会触发表单默认提交行为,导致页面刷新。刷新后路由的location.state会丢失,因此出现Cannot read properties of null (reading 'username')错误,URL末尾的问号是表单默认GET提交的产物。
具体解决方案
1. 阻止表单默认提交行为(最直接修复)
有两种实现方式:
- 方式一:修改按钮类型
给「Update/Create」和「Delete」按钮添加type="button"属性,避免触发表单提交:<button type="button" className='pres-update' onClick={() => {handleUpdate()}}>Update/Create</button> <button type="button" className='pres-delete'>Delete</button> - 方式二:在点击事件中阻止默认行为
修改handleUpdate函数,接收事件参数并调用preventDefault():const handleUpdate = async (e) => { e.preventDefault(); // 阻止表单默认提交 if(id !== "") { // 原fetch逻辑保持不变 } } // 同步修改按钮的onClick: <button className='pres-update' onClick={(e) => {handleUpdate(e)}}>Update/Create</button>
2. 安全访问location.state
即使解决了刷新问题,也可能存在路由state未传递的场景,建议添加空值保护:
// 解构时添加默认值 const { state = {} } = useLocation(); const doctorUsername = state.username || ''; // 后续使用时用doctorUsername替代location.state.username useEffect(() => { if(doctorUsername) { fetch(`https://localhost:44304/api/Patient/GetPatientsByDoctor?doctorUsername=${doctorUsername}`) .then(response => response.json()) .then(setPatients) } }, [doctorUsername])
3. 替换全局变量为useState(优化代码健壮性)
当前代码中id和patientName是全局变量,组件重渲染时可能出现值异常,建议改为组件内部状态:
export const DocPres = () => { // 新增两个状态 const [id, setId] = useState(""); const [patientName, setPatientName] = useState(""); // 修改getPrescriptions函数 const getPrescriptions = (e) => { fetch(`https://localhost:44304/api/Prescription/GetPrescriptionsByPatient?patientUsername=${e}`) .then(response => response.json()) .then(setPrescriptions) setPatientName(e); setId(""); // 其他状态重置逻辑不变 } // 修改populateData函数中的id赋值 const populateData = (e) => { if(typeof(e) === 'string') { var result = e.includes("ID") if(e==="New"){ setId(""); // 其他重置逻辑不变 } else if(result===true) { setId(e.slice(5)); // 原fetch逻辑不变 } } else { setId(""); // 其他重置逻辑不变 } } }
为什么之前的useNavigate尝试无效?
因为页面刷新是表单默认行为触发的,优先级高于自定义导航逻辑,必须先阻止默认提交行为,再进行其他操作。
内容的提问来源于stack exchange,提问作者Lucas F
相关产品推荐
相关产品推荐

