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

React Router获取URL参数后隐藏地址栏参数的实现问题

问题:隐藏URL中的敏感参数并保持当前组件页面

我有一个URL:http://localhost:3000/MockApi/getDetails/A1B@$CZSK_2,希望在跳转到对应的App组件后,隐藏地址栏URL中的A1B@$CZSK_2部分,同时停留在该组件页面。尝试过MemoryRouter、useNavigate、useHistory,但都没有效果,寻求解决方案。

现有代码

App组件代码

import 'bootstrap/dist/css/bootstrap.min.css';
import './App.css';
import React, { useEffect, useState } from 'react';
import { useParams } from 'react-router-dom';

function App() {
  const [data, setData] = useState<any>(null);
  const { key } = useParams();
  
  useEffect(() => {
    const apiUrl = `http://localhost:8080/MockApi/getDetails/${key}`;
    fetch(apiUrl)
      .then(response => {
        if (!response.ok) {
          throw new Error('Network response was not ok');
        }
        return response.json();
      })
      .then(data => {
        setData(data);
        console.log(data);
      })
      .catch(error => {
        console.error('Error fetching data:', error);
      });
  }, [key]);

  return (
    <div className="container col-12 col-md-3 mt-5 ">
      <div>
        <div className="row justify-content-center border border-secondary p-3 rounded text-center shadow">
          <div className="col-md-7">
            <h2 className="text-center">ABC Company</h2>
            <form className="mt-3 text-center">
              <div className='container'>
                {data && <h4 className="text-center pt-5">MSISDN: {data.msisdn}</h4>}
                {data && <h4 className="text-center pt-5">ServerRef: {data.severRef}</h4>}   
              </div>
  
              <div className="mb-3 pt-5 text-center">
                <input
                  type="text"
                  name="OTP"
                  className="form-control"
                  placeholder="OTP"
                />
              </div>
              <button type="submit" className="btn btn-primary w-100">
                Submit
              </button>
            </form>
          </div>
        </div>
      </div>
    </div>
  );
}
  
export default App;

路由配置代码

import './App.css';
import '../node_modules/bootstrap/dist/css/bootstrap.min.css';
import {BrowserRouter as Routes, Route, Router } from 'react-router-dom';
import Home from './home';

function MainApp() {
  return (
    <div className="App">
    <Router basename='/api' location={"/"} navigator={}>
        <Routes>
          <Route path="/MockApi/getDetails/:key" element={<Home />} />
        </Routes>
      </Router>
    </div>
  );
}

export default MainApp;

解决方案

1. 修正路由配置错误

你的路由导入和使用存在错误,BrowserRouter不能别名成Routes,同时需要添加无参数的路由规则,确保URL修改后组件仍能匹配:

import './App.css';
import '../node_modules/bootstrap/dist/css/bootstrap.min.css';
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import Home from './home'; // 注意:确保组件导入路径与实际文件一致

function MainApp() {
  return (
    <div className="App">
      <Router basename='/api'>
        <Routes>
          {/* 不带参数的路由,用于隐藏参数后的URL匹配 */}
          <Route path="/MockApi/getDetails" element={<Home />} />
          {/* 带参数的路由,用于初始跳转 */}
          <Route path="/MockApi/getDetails/:key" element={<Home />} />
        </Routes>
      </Router>
    </div>
  );
}

export default MainApp;

2. 在App组件中修改URL并保留参数数据

使用useNavigate的replace方法替换当前URL,同时将参数存储在组件状态中,避免路由跳转后丢失数据:

import 'bootstrap/dist/css/bootstrap.min.css';
import './App.css';
import React, { useEffect, useState } from 'react';
import { useParams, useNavigate } from 'react-router-dom';

function App() {
  const [data, setData] = useState<any>(null);
  const [apiKey, setApiKey] = useState<string | undefined>(undefined);
  const { key } = useParams();
  const navigate = useNavigate();
  
  useEffect(() => {
    // 优先使用组件内部存储的key,避免路由跳转后丢失参数
    const targetKey = apiKey || key;
    if (!targetKey) return;

    const apiUrl = `http://localhost:8080/MockApi/getDetails/${targetKey}`;
    fetch(apiUrl)
      .then(response => {
        if (!response.ok) {
          throw new Error('Network response was not ok');
        }
        return response.json();
      })
      .then(data => {
        setData(data);
        // 仅在初始带参数跳转时修改URL
        if (key && !apiKey) {
          setApiKey(key);
          // 替换URL为不带参数的路径,不会添加历史记录
          navigate('/MockApi/getDetails', { replace: true });
        }
      })
      .catch(error => {
        console.error('Error fetching data:', error);
      });
  }, [key, apiKey, navigate]);

  return (
    <div className="container col-12 col-md-3 mt-5 ">
      <div>
        <div className="row justify-content-center border border-secondary p-3 rounded text-center shadow">
          <div className="col-md-7">
            <h2 className="text-center">ABC Company</h2>
            <form className="mt-3 text-center">
              <div className='container'>
                {data && <h4 className="text-center pt-5">MSISDN: {data.msisdn}</h4>}
                {data && <h4 className="text-center pt-5">ServerRef: {data.severRef}</h4>}   
              </div>
  
              <div className="mb-3 pt-5 text-center">
                <input
                  type="text"
                  name="OTP"
                  className="form-control"
                  placeholder="OTP"
                />
              </div>
              <button type="submit" className="btn btn-primary w-100">
                Submit
              </button>
            </form>
          </div>
        </div>
      </div>
    </div>
  );
}
  
export default App;

关键说明

  • 使用navigate.replace而非navigate.push:替换当前历史记录条目,避免用户点击后退回到带参数的URL。
  • 组件内部存储apiKey:路由跳转后useParams无法获取参数,将参数存在状态中确保后续操作能正常获取。
  • 添加无参数路由规则:保证URL修改后,组件仍能被正确匹配渲染。

内容的提问来源于stack exchange,提问作者Nirosh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 16:05:44