如何在 react-router-dom v6 中监听路由变化

how to listen for route change in react-router-dom v6

我正在尝试将旧的 React 路由器 dom 代码迁移到 v6,我想知道如何监听路由更改,我现在正在使用 useHistory

const history = useHistory()
//then
history.listen(...)

我确实阅读了新文档,并且确实发现 useHistory 已更改为 useNavigate

const navigate = useNavigate()
//then
navigate.listen(...) // listen is not a function

你能帮我找到一种方法来监听 v6 中的路由变化吗

// This is a React Router v6 app
import { useNavigate } from "react-router-dom";

function App() {
  let navigate = useNavigate();
  function handleClick() {
    navigate("/home");
  }
  return (
    <div>
      <button onClick={handleClick}>go home</button>
    </div>
  );
}

navigate 函数是一个函数,而不是像旧 react-router-dom 版本 5 的 history 对象那样的对象。

您仍然可以创建自定义 history 对象,但您需要创建自定义路由器才能使用它。这允许您导入 您的 history 对象并创建侦听器。

创建一个自定义路由器示例,以其中一个更高级别的路由器为例,说明它们如何管理位置和状态,即 BrowserRouter:

const CustomRouter = ({ history, ...props }) => {
  const [state, setState] = useState({
    action: history.action,
    location: history.location
  });

  useLayoutEffect(() => history.listen(setState), [history]);

  return (
    <Router
      {...props}
      location={state.location}
      navigationType={state.action}
      navigator={history}
    />
  );
};

在您的代码中创建自定义 history 对象以供您的新自定义路由器和其他组件使用。

const history = createBrowserHistory();
export default history;

使用你的路由器并将你的历史对象传递给它。

import CustomRouter from '../CustomRouter';
import history from '../myHistory';

...

<CustomRouter history={history}>
  ....
</CustomRouter>

在您想要监听位置变化的组件中,导入您的历史对象并像之前一样调用 listen 回调。

import history from '../myHistory';

...

useEffect(() => {
  const unlisten = history.listen((location, action) => {
    // ... logic
  });

  return unlisten;
}, []);

如果需要,您还可以创建自己的自定义 useHistory 挂钩,它只是 returns 您的历史对象。

要添加已接受的答案(无法评论,没有足够的代表点),如果导航卸载组件,则通过依赖项数组中带有 location.pathname 的 useEffect 订阅历史记录将不起作用您正在尝试从以下位置调用 useEffect。

根据文档 (https://reactrouter.com/docs/en/v6/hooks/use-location),使用此挂钩

let location = useLocation();

React.useEffect(() => {
  ga('send', 'pageview');
}, [location]);