React Router 4.x下未配置路由的组件跳转实现方案咨询
解决React Router 4.x中跳转未配置组件的问题
先帮你修正现有代码里的明显错误,避免后续出现奇怪的路由问题:
修正后的基础代码
index.js
import { BrowserRouter as Router, Route } from 'react-router-dom' import App from './App' import ReactDOM from 'react-dom' const WrappedApp = ( <Router> {/* 修正原代码中path={App}的错误,应该用component={App}指定渲染组件 */} <Route component={App} /> </Router> ) ReactDOM.render(WrappedApp, document.getElementById('root'));
App.js
import React from 'react' import { Switch, Route } from 'react-router-dom' import MyComponent1 from 'path/to/component1' // 修正重复导入的问题 import MyComponent2 from 'path/to/component2' // 先引入你要跳转的目标组件,示例命名为TargetComponent import TargetComponent from 'path/to/TargetComponent' export default class App extends React.Component { render() { return ( <Switch> {/* Route标签需闭合,添加exact避免根路径匹配所有子路径 */} <Route exact path='/' component={MyComponent1} /> <Route path='/2' component={MyComponent2} /> {/* 提前配置目标组件的路由,这是Router 4.x实现跳转的核心前提 */} <Route path='/target' component={TargetComponent} /> </Switch> ) } }
两种实现跳转的实用方式
方式1:用Link组件实现静态跳转
如果只是单纯的点击跳转,直接用react-router-dom提供的Link组件包裹按钮即可,代码更简洁:
import React from 'react' import { Link } from 'react-router-dom' class MyComponent2 extends React.Component { render() { return ( <div> <Link to='/target'> <button>跳转到目标组件</button> </Link> </div> ) } } export default MyComponent2
方式2:用history.push实现事件驱动跳转
如果需要在表单提交、异步请求完成等事件后跳转,就用组件自带的props.history对象来触发跳转:
import React from 'react' class MyComponent2 extends React.Component { handleSubmit = () => { // 这里可以编写表单验证、提交接口等逻辑 console.log('提交完成,准备跳转') // 调用history.push跳转到目标路由 this.props.history.push('/target') } render() { return ( <div> <button onClick={this.handleSubmit}>提交并跳转</button> </div> ) } } export default MyComponent2
注意:如果你的组件不是直接被
Route渲染的(没有自动注入history属性),可以用withRouter高阶组件包裹组件来获取history:import { withRouter } from 'react-router-dom' // 组件定义保持不变 export default withRouter(MyComponent2)
动态添加路由(应对临时新增组件的场景)
如果你的需求是动态添加完全未预先配置的路由,可以通过在App组件中维护路由列表状态来实现:
修改后的App.js
import React from 'react' import { Switch, Route } from 'react-router-dom' import MyComponent1 from 'path/to/component1' import MyComponent2 from 'path/to/component2' export default class App extends React.Component { state = { // 初始化基础路由列表 routes: [ { path: '/', component: MyComponent1, exact: true }, { path: '/2', component: MyComponent2 } ] } // 提供添加路由的方法,传递给子组件调用 addRoute = (newRoute) => { this.setState(prevState => ({ routes: [...prevState.routes, newRoute] })) } render() { return ( <> <Switch> {/* 动态渲染路由列表 */} {this.state.routes.map((route, index) => ( <Route key={index} path={route.path} component={route.component} exact={route.exact || false} /> ))} </Switch> {/* 通过render属性把addRoute方法传递给MyComponent2 */} <Route path='/2' render={(props) => <MyComponent2 {...props} addRoute={this.addRoute} />} /> </> ) } }
在MyComponent2中动态添加并跳转
import React from 'react' // 引入需要动态添加的组件 import DynamicComponent from 'path/to/DynamicComponent' class MyComponent2 extends React.Component { handleDynamicJump = () => { // 先添加新路由配置 this.props.addRoute({ path: '/dynamic', component: DynamicComponent }) // 立即跳转到新增的路由 this.props.history.push('/dynamic') } render() { return ( <div> <button onClick={this.handleDynamicJump}>动态添加并跳转</button> </div> ) } } export default MyComponent2
关键提示
React Router 4.x采用声明式路由,所有可跳转的组件都必须对应一个路由配置——不管是预先写好的还是动态添加的。另外,记得给根路径路由加上exact属性,避免它匹配所有以/开头的子路径,导致路由优先级混乱。
内容的提问来源于stack exchange,提问作者Malakai
相关产品推荐
相关产品推荐

