使用React Router v4实现下拉选择跳转时出现错误
解决React Router v4下拉菜单跳转后消失及同路由警告问题
问题拆解
先帮你理清这两个问题的根源:
- 下拉选择框消失:大概率是你的下拉组件只绑定在某个特定路由的页面组件中,当路由跳转后,原页面组件被卸载,下拉框自然跟着消失了。比如下拉组件放在首页里,跳转到新闻页后首页组件被移除,下拉框也就不见了。
- 同路由跳转警告:当用户当前已经处在
/you/your-favorite-news路由时,又选择了对应选项触发跳转,React Router会检测到跳转到完全相同的路由,因此抛出这个警告。
针对性解决方案
1. 让下拉组件全局常驻(解决消失问题)
把下拉组件移到路由规则的外层,也就是BrowserRouter内部、Switch外部的位置,这样不管路由怎么切换,下拉组件都会一直渲染在页面上。示例代码如下:
import React from 'react'; import { BrowserRouter, Switch, Route } from 'react-router-dom'; import YourDropdown from './YourDropdown'; // 你的下拉组件 import Home from './Home'; import FavoriteNews from './FavoriteNews'; function App() { return ( <BrowserRouter> {/* 下拉组件放在Switch外,所有路由下都能显示 */} <YourDropdown /> <Switch> <Route path="/" exact component={Home} /> <Route path="/you/your-favorite-news" component={FavoriteNews} /> {/* 其他路由规则... */} </Switch> </BrowserRouter> ); } export default App;
2. 拦截同路由跳转(解决警告问题)
在下拉组件的选择事件处理逻辑里,先判断当前路由和目标路由是否一致,只有不一致时才执行跳转操作。
函数组件版本
import React from 'react'; import { useHistory, useLocation } from 'react-router-dom'; function YourDropdown() { const history = useHistory(); const location = useLocation(); const handleSelect = (event) => { const targetPath = event.target.value; // 先校验当前路径和目标路径是否相同 if (location.pathname !== targetPath) { history.push(targetPath); } // 路径相同时什么都不做,避免触发警告 }; return ( <select onChange={handleSelect}> <option value="/">首页</option> <option value="/you/your-favorite-news">我的收藏新闻</option> {/* 其他选项... */} </select> ); } export default YourDropdown;
类组件版本
如果你的下拉组件是类组件,需要用withRouter高阶组件注入路由相关属性:
import React, { Component } from 'react'; import { withRouter } from 'react-router-dom'; class YourDropdown extends Component { handleSelect = (event) => { const targetPath = event.target.value; const { history, location } = this.props; if (location.pathname !== targetPath) { history.push(targetPath); } }; render() { return ( <select onChange={this.handleSelect}> <option value="/">首页</option> <option value="/you/your-favorite-news">我的收藏新闻</option> </select> ); } } export default withRouter(YourDropdown);
额外优化:高亮当前路由对应的选项
如果需要让下拉框自动高亮当前路由对应的选项,可以用location.pathname匹配选项的value,添加selected属性:
<option value="/you/your-favorite-news" selected={location.pathname === "/you/your-favorite-news"} > 我的收藏新闻 </option>
这样处理后,两个问题都能得到解决啦。
内容的提问来源于stack exchange,提问作者grazdev
相关产品推荐
相关产品推荐

