在浏览器的后退按钮上反应路由器历史

React Router history on browser's back button

我有一个带有 link 的主页组件,它加载了一个显示组件,在显示组件中我有相同的 link,它再次加载了显示组件。

如果用户在 Display Component 中多次点击 link 那么会有很多路由器 history.i 希望当用户点击浏览器后退按钮时它应该加载 home 组件而不是全部以前的历史。

当我在带有 onClick 事件的 Display 组件中使用 history.replace("/"); 时,它只工作一次 back.but 再次返回导致 Display Component 的先前历史记录

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>

根据您使用的 React 路由器的版本,您可以在 Display.js 文件中的 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']

按下浏览器后退按钮会触发 window popstate 事件。流行是那里的关键词。当按下浏览器后退按钮时,您的历史记录看起来像这样 ['/home', '/city1', '/city2'],这就是您看到历史记录中不同城市的原因。

相反,您想使用替换来达到预期的效果

history.replace('/city1') // ['/home', '/city1']
history.replace('/city2') // ['/home', '/city2']
history.replace('/city3') // ['/home', '/city3']