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

React+TS类组件fetch成功后如何带参跳转且不暴露URL参数

解决方案

你遇到的是类组件无法直接使用react-router-dom v6 Hook、跳转传参不希望暴露在URL的问题,可通过以下步骤实现需求:

1. 封装自定义withRouter高阶组件

react-router v6 已移除内置的withRouter API,我们自行封装一个高阶组件,为类组件注入路由能力:

import { useNavigate, useLocation } from 'react-router-dom';
import React from 'react';

type WithRouterProps = {
  navigate: (to: string, options?: { state?: any, replace?: boolean }) => void;
  location: Location;
}

export function withRouter<T extends WithRouterProps>(Component: React.ComponentType<T>) {
  return (props: Omit<T, keyof WithRouterProps>) => {
    const navigate = useNavigate();
    const location = useLocation();
    return <Component {...props as T} navigate={navigate} location={location} />;
  };
}

2. 修改登录组件代码

调整你的Modal组件的Props定义,在登录成功后调用注入的navigate方法,通过state参数传递数据(该参数不会出现在URL中):

// 调整Props接口,新增navigate属性
interface MyProps extends WithRouterProps {}
interface MyStates{
  username: string,
  password: string
}

class Modal extends React.Component<MyProps, MyStates>{
  constructor(props: MyProps){
    super(props);
    this.state = {username: '', password: ''};

    this.handleUsernameChange = this.handleUsernameChange.bind(this);
    this.handlePasswordChange = this.handlePasswordChange.bind(this);
    this.handleLoginSubmit = this.handleLoginSubmit.bind(this);
  }

  handleUsernameChange(event: React.ChangeEvent<HTMLInputElement>) {
    this.setState({username: event.target.value});
  }

  handlePasswordChange(event: React.ChangeEvent<HTMLInputElement>) {
    this.setState({password: event.target.value});
  }
  
  handleLoginSubmit(event: React.FormEvent<HTMLFormElement>) {
    event.preventDefault();
    const request = {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ username: this.state.username, password: this.state.password})
    }
    fetch('login',request)
    .then(response => {
      if(!response.ok) throw new Error(response.statusText);
      return response.json(); // 建议解析后端返回的token、用户信息等数据
    })
    .then(res => {
      // 敏感凭证如token建议存入sessionStorage,刷新页面不会丢失
      sessionStorage.setItem('token', res.token);
      // 跳转时通过state传递非敏感参数,不会出现在URL
      this.props.navigate('/after-login', {
        state: {
          username: this.state.username
        },
        replace: true // 可选,防止用户回退到登录页
      });
    })
    .catch(err => {
      // 处理登录失败逻辑
      console.error('登录失败:', err);
    })
  }
  render(){
    return <div className='Modal'>
          
            <form onSubmit= { this.handleLoginSubmit }>
              <label>
                Username
              <input type='text' name='username' value={this.state.username} onChange={this.handleUsernameChange} />
              </label>
              <p/>
              <label>
                Password
              <input type='password' name='password' value={this.state.password} onChange={this.handlePasswordChange} />
              </label>
              <p/>
              <button> Sign In</button>
            </form>
          
        </div>
  }
}

// 导出组件时用withRouter包裹,注入路由能力
export default withRouter(Modal);

3. 目标页面获取传递的参数

如果目标页面是函数组件,直接使用useLocation Hook获取state参数:

import { useLocation } from 'react-router-dom';

const AfterLoginPage = () => {
  const location = useLocation();
  // 获取跳转传递的用户名
  const username = location.state?.username;
  // 也可以从sessionStorage获取token做身份校验
  const token = sessionStorage.getItem('token');

  return <div>欢迎回来,{username}</div>
}

如果目标页面是类组件,同样使用上面的withRouter高阶组件包裹,从props.location.state中读取参数即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 11:45:04