如何在按钮点击回调函数的if/else分支中使用React Router
问题根因
<Routes>、<Route>是路由规则声明组件,仅能放在组件JSX渲染树中用于定义路径和组件的匹配关系,写在点击事件回调里的JSX不会被React渲染,完全无法触发跳转。
点击事件中要切换路由,必须使用React Router提供的编程式导航API,且路由规则需要提前在应用根层级声明。
React Router v6 实现方案(当前主流版本)
- 首先在应用根组件完成路由规则配置,不要把路由声明写到事件逻辑里:
// App.jsx import { BrowserRouter, Routes, Route } from 'react-router-dom' import ButtonPage from './pages/ButtonPage' // 放置触发按钮的业务页面 import EmailInput from './pages/EmailInput' function App() { return ( <BrowserRouter> <Routes> <Route path="/" element={<ButtonPage />} /> <Route path="/EmailInput" element={<EmailInput />} /> </Routes> </BrowserRouter> ) } export default App
- 在放置按钮的业务组件中,调用
useNavigate钩子获取跳转方法,在点击回调中执行跳转:
// ButtonPage.jsx import { useNavigate } from 'react-router-dom' function ButtonPage() { const navigate = useNavigate() const handleStartClick = () => { const email = localStorage.getItem('email') if (email?.length) { alert('not empty!') } else { navigate('/EmailInput') } } return <button onClick={handleStartClick}>开始</button> } export default ButtonPage
React Router v5 兼容方案(旧版本)
如果你的项目还在使用v5版本,用useHistory钩子替代useNavigate即可,路由规则仍需提前在根组件声明:
import { useHistory } from 'react-router-dom' function ButtonPage() { const history = useHistory() const handleStartClick = () => { const email = localStorage.getItem('email') if (email?.length) { alert('not empty!') } else { history.push('/EmailInput') } } return <button onClick={handleStartClick}>开始</button> }
注意事项
useNavigate、useHistory这类路由钩子只能在Router组件(BrowserRouter/HashRouter等)包裹的子组件内调用,否则会抛错。- 如果跳转需要替换历史记录(避免用户点返回回到当前页),可以给
navigate加第二个参数:navigate('/EmailInput', { replace: true }),v5对应写法是history.replace('/EmailInput')。
内容的提问来源于stack exchange,提问作者deoxzy
相关产品推荐
相关产品推荐

