You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 01:26:59