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
相关产品推荐
相关产品推荐

