在浏览器的后退按钮上反应路由器历史记录
Posted
技术标签:
【中文标题】在浏览器的后退按钮上反应路由器历史记录【英文标题】:React Router history on browser's back button 【发布时间】:2021-10-27 20:45:33 【问题描述】:我有一个带有加载显示组件的链接的主组件,并且在显示组件中我有相同的链接再次加载显示组件。
如果用户在显示组件中多次单击该链接,则会有很多路由器历史记录。我希望当用户单击浏览器后退按钮时,它应该加载主组件,而不是所有以前的历史记录。
当我在带有 onClick 事件的 Display 组件中使用 history.replace("/");
时,它只会返回一次。但再次返回会导致 Display 组件的先前历史记录
Routes.js
import Home from "./Components/Home"
import Display from "./Components/Display"
<Router>
<Switch>
<Route exact path="/">
<Home />
</Route>
<Route path="/:city">
<Display />
</Route>
</Switch>
</Router>
Home.js
<Link to =`/$city` onClick=()=>dispatch(fetchWeather(city)); >Search</Link>
Display.js
<Link to =`/$city` onClick=()=>dispatch(fetchWeather(city)); >Search</Link>
【问题讨论】:
您是否尝试告诉链接组件替换?<Link replace to= />
。或者,您可以定义一个函数来为您处理此问题,而不是让链接的默认重定向行为通过,而是使用反应路由器 history
替换 Display
中的状态。这样,每一次城市点击都会用新的目标更新当前的历史状态......并且按下后退按钮将返回主页。如果这对你有用,我很乐意把它写成答案:)
同意,Display
中的 Link
应该是重定向到自己 (REPLACE
),而不是导航 (PUSH
)。这只会替换当前条目,而不是逐页推送。完成后退导航 (POP
) 后,用户返回主页。
@JohnRuddell 你能写出答案吗,我很想看看应该如何实现:-)
@Shyam 这实际上是只是将replace
属性添加到Link
。 reactrouter.com/web/api/Link/replace-bool
@DrewReese 哦,好吧,以前没遇到过这个用例。很高兴知道。
【参考方案1】:
根据您使用的 react 路由器的版本,您只需在 Link
文件中的 Link
组件上添加 replace
属性,即可不在历史堆栈中推送新状态,而是更新当前状态。
<Link replace to =`/$city` onClick=()=>dispatch(fetchWeather(city)); >Search</Link>
如果您使用的是不支持此功能的旧版本,您可以让点击处理程序为您执行此操作
// Display.js file
function Display(props)
// whatever code you have for this file
const handleViewCity = useCallback((event, city) =>
// prevent the default redirect from happening, were going to manage that ourselves
event.preventDefault()
dispatch(fetchWeather(city))
props.history.replace(`/$city`)
, [props.history, fetchWeather])
return (
// your jsx
// keep the href so you get browser builtin functionality like right click "open in new window"
<a href=`/$city` onClick=(e) => handleViewCity(e, city)>Search</Link>
)
export default withRouter(Display)
为了形象化这里会发生什么,可以将历史想象成一堆地点。 (这是一个简单的例子——伪代码)
history.push('/city1') // ['/home', '/city1']
history.push('/city2') // ['/home', '/city1', '/city2']
history.push('/city3') // ['/home', '/city1', '/city2', '/city3']
按下浏览器后退按钮会触发一个窗口popstate
事件。流行音乐是那里的关键词。当按下浏览器后退按钮时,您的历史记录看起来像这样['/home', '/city1', '/city2']
,这就是为什么您会看到历史记录中的不同城市。
相反,您想使用替换来达到预期的效果
history.replace('/city1') // ['/home', '/city1']
history.replace('/city2') // ['/home', '/city2']
history.replace('/city3') // ['/home', '/city3']
【讨论】:
以上是关于在浏览器的后退按钮上反应路由器历史记录的主要内容,如果未能解决你的问题,请参考以下文章