不使用React Hooks如何实现页面切换?React Router导航失败求助
问题解决:React Router Link导航失败 & 非Hooks方式页面切换
一、修复Link导航到/Mypath失败的问题
你的代码里有几个关键问题,逐个修正就能解决:
- 修正Link的to属性语法错误
你写的<Link to="/Mypath>"多了一个冗余的闭合引号,正确写法是:
<Link to="/Mypath"><ButtonLogReg onClick={handler}>READY</ButtonLogReg></Link>
- 处理handler阻止默认跳转的问题
ButtonLogReg的onClick事件里调用了event.preventDefault(),这会直接阻止Link的默认导航行为,分两种情况处理:
- 如果不需要先执行异步操作,直接删掉
event.preventDefault(),让Link的默认跳转逻辑生效。 - 如果需要先执行
asyncFunction再导航,改用useNavigate手动触发导航,同时修正try/catch的语法错误:
import { useNavigate } from 'react-router-dom' function Launcher() { // ...其他代码 const navigate = useNavigate(); const handler = async (event) => { event.preventDefault(); // 阻止Link默认跳转 try { await asyncFunction(); // 异步函数必须加await才能捕获错误 navigate("/Mypath"); // 执行完异步操作后手动导航 } catch (error) { // 这里可以调用showAlert处理错误,比如:showAlert(error.message) } }; // ...渲染代码 }
- 修正try/catch语法错误
你原来的try(asyncFunction())catch(error)是错误语法,try后面必须用大括号包裹代码块,且异步函数需要await才能在catch中捕获异步错误,上面的代码已经修正了这一点。
二、不使用React Hooks实现页面切换
如果是类组件场景,可以用以下两种方式:
1. React Router v5 用withRouter高阶组件
通过withRouter把路由相关的history对象注入到组件props中,用history.push跳转:
import React from 'react'; import { withRouter } from 'react-router-dom'; import ButtonLogReg from "../components/ButtonLogReg"; class Launcher extends React.Component { handler = async (event) => { event.preventDefault(); try { await asyncFunction(); this.props.history.push("/Mypath"); // 手动跳转 } catch (error) { // 错误处理逻辑 } }; render() { return ( <main> <nav> <h2>Go?</h2> <ButtonLogReg onClick={this.handler}>READY</ButtonLogReg> <h2 onClick={() => this.props.history.push("/")}>Back</h2> </nav> </main> ); } } export default withRouter(Launcher);
2. React Router v6 用Navigate组件配合状态
v6移除了withRouter,可以通过状态控制Navigate组件渲染来实现跳转:
import React from 'react'; import { Navigate } from 'react-router-dom'; import ButtonLogReg from "../components/ButtonLogReg"; class Launcher extends React.Component { state = { shouldNavigate: false, targetPath: "" }; handler = async (event) => { event.preventDefault(); try { await asyncFunction(); this.setState({ shouldNavigate: true, targetPath: "/Mypath" }); } catch (error) { // 错误处理逻辑 } }; render() { // 如果需要跳转,渲染Navigate组件 if (this.state.shouldNavigate) { return <Navigate to={this.state.targetPath} replace />; } return ( <main> <nav> <h2>Go?</h2> <ButtonLogReg onClick={this.handler}>READY</ButtonLogReg> <h2 onClick={() => this.setState({ shouldNavigate: true, targetPath: "/" })}>Back</h2> </nav> </main> ); } } export default Launcher;
内容的提问来源于stack exchange,提问作者xavi zamora
相关产品推荐
相关产品推荐

