如何在React中处理路由转换后标题未更新的问题?

新手上路,请多包涵

我在写React程序的时候,我使用useEffect钩子函数来更新路由转换后的标题,发现在Effect中的回调函数执行时,document.title打印值还是跳转之前的值,useEffect钩子函数是在Dom渲染完成后执行的,但此时不知道为什么标题未发生改变,可能是我的当时不对,怎样才可以实现?
代码如下:

import { useEffect, useRef } from "react";
import { useLocation } from "react-router-dom";

export default function useRouterTracking() {
  const viewNumber = useRef({});
  const location = useLocation();
  const pathname = useRef(null);
  const title = useRef(document.title);

  useEffect(() => {
    console.log(document.title)
    pathname.current = location.pathname;
    title.current = document.title;

    if (title.current in viewNumber.current) viewNumber.current[title.current] += 1;
    else viewNumber.current[title.current] = 1;
    console.log(viewNumber.current);
  }, [location.pathname]);
}

如上,如何获取路由更新后的标题呢?

阅读 857
avatarAI BotBETA

这个问题可能是由于React的useEffect在组件渲染完成前就执行导致的。在useEffect中,你试图获取并打印当前的document.title,然而在此时,React可能还没有更新DOM,因此你获取到的还是旧的标题。

一个可能的解决方案是使用useEffect的依赖数组来解决这个问题。你可以将location.pathnamedocument.title都作为useEffect的依赖,这样当它们中的任何一个发生改变时,useEffect都会被触发。

下面是你的代码的修改版:

import { useEffect, useRef, useState } from "react";
import { useLocation } from "react-router-dom";

export default function useRouterTracking() {
  const viewNumber = useRef({});
  const location = useLocation();
  const pathname = useRef(null);
  const [title, setTitle] = useState(document.title);

  useEffect(() => {
    console.log(title); // 打印当前的标题
    pathname.current = location.pathname;
    setTitle(document.title); // 更新标题的状态

    if (title in viewNumber.current) viewNumber.current[title] += 1;
    else viewNumber.current[title] = 1;
    console.log(viewNumber.current);
  }, [location.pathname, title]); // 当路径名和标题改变时,执行此effect
}

这个修改版的代码应该可以在你路由转换后更新标题。然后你可以在需要的地方使用useRouterTracking这个hook来获取路由转换后的标题。

2 个回答

有点没看懂你代码意图。
如果是想让每个路由自动设置页面标题,可以看看下面的示例代码有没有帮助:

import React from 'react';
import { createBrowserRouter } from 'react-router-dom';

import Root from './Root';
import Public from './Public';

function PageTitleWrap({ title, children }) {
  React.useEffect(() => {
    document.title = title;
  }, [title]);

  return children;
}

const router = createBrowserRouter([
  {
    path: '/',
    element: (
      <PageTitleWrap title="首页">
        <Root />
      </PageTitleWrap>
    ),
  },
  {
    path: '/public',
    element: (
      <PageTitleWrap title="公共页">
        <Public />
      </PageTitleWrap>
    ),
  },
]);

export default router;

只读取了document.title,并没有修改。

另外,仅从这个代码片段来看,没看出来能实现什么具体功能,既没使用状态管理,也没返回状态,换句话说,只是一段没用的代码。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题