React router v6 History.listen

Hum*_*l37 26 reactjs react-router

在 React Router v5 中,历史对象有一个监听方法。使用该方法,我编写了一个 usePathname 挂钩来在路径更改时重新呈现组件。在 React Router v6 中,这个方法不再存在。像这样的事情有替代方案吗?我不想使用 useLocation 因为如果状态发生变化它也会呈现,而在本例中我不需要。

该钩子与 v5 一起使用。

import React from "react";
import { useHistory } from "react-router";

export function usePathname(): string {
  let [state, setState] = React.useState<string>(window.location.pathname);

  const history = useHistory();
  React.useLayoutEffect(
    () =>
      history.listen((locationListener) => setState(locationListener.pathname)),
    [history]
  );
  return state;
}
Run Code Online (Sandbox Code Playgroud)

yuv*_*.bl 8

如上所述,每当当前位置发生变化时, useLocation可用于执行副作用。

typescript这是我的位置更改“监听器”挂钩的简单实现。应该可以帮助你得到你正在寻找的结果

function useLocationEffect(callback: (location?: Location) => any) {
  const location = useLocation();

  useEffect(() => {
    callback(location);
  }, [location, callback]);
}

// usage:
useLocationEffect((location: Location) => 
  console.log('changed to ' + location.pathname));
Run Code Online (Sandbox Code Playgroud)


Hum*_*l37 7

我现在正在使用这段代码

import { BrowserHistory } from "history";
import React, { useContext } from "react";
import { UNSAFE_NavigationContext } from "react-router-dom";

export default function usePathname(): string {
  let [state, setState] = React.useState<string>(window.location.pathname);

  const navigation = useContext(UNSAFE_NavigationContext)
    .navigator as BrowserHistory;
  React.useLayoutEffect(() => {
    if (navigation) {
      navigation.listen((locationListener) =>
        setState(locationListener.location.pathname)
      );
    }
  }, [navigation]);

  return state;
}
Run Code Online (Sandbox Code Playgroud)

看起来效果很好

  • 这在带有 DataBrowserRouter 的 React Router 6.4 中不再起作用。 (2认同)