考虑以下代码:

https://codesandbox.io/p/sandbox/hardcore-lake-mptzw3

App.jsx:

import ContextProvider from "./provider/contextProvider";
import Routes from "./routes";
function App() {
  console.log("In App");

  return (
    <ContextProvider>
      <Routes />
    </ContextProvider>
  );
}

export default App;

Routes.jsx:

import { RouterProvider, createBrowserRouter } from "react-router-dom";
import { provideContext } from "./provider/contextProvider";
import Component1 from "./pages/Component1";
import Component2 from "./pages/Component2";
const Routes = () => {
  const { token } = provideContext();

  const router = createBrowserRouter([
    {
      path: "/Component2",
      element: <Component2 />,
    },
    {
      path: "/Component1",
      element: <Component1 />,
    },
  ]);


  return <RouterProvider router={router} />;
};

export default Routes;

pages/vent1.jsx:

const Component1 = () => {
  console.log("In Component1");

  return <div>Component1</div>;
};

export default Component1;

pages/vent2.jsx:

import { useNavigate } from "react-router-dom";
import { provideContext } from "../provider/contextProvider";

const Component2 = () => {
  const navigate = useNavigate();
  const { setToken } = provideContext();
  console.log("In Component2");
  const onClick = () => {
    setToken("Token");
    setTimeout(() => {
      navigate("/Component1");
    });
  };

  return (
    <>
      <button onClick={onClick}>Click me</button>
    </>
  );
};

export default Component2;

contextprovider. jsx:

import { createContext, useContext, useState } from "react";

const Context = createContext();

const ContextProvider = ({ children }) => {
  const [token, setToken] = useState("Initial");

  return (
    <Context.Provider value={{ token, setToken }}>{children}</Context.Provider>
  );
};

export const provideContext = () => {
  return useContext(Context);
};

export default ContextProvider;

当点击Component2中的按钮时,URL发生了变化,但UI仍然显示Component2.Component 1章一次都没有

有趣的是,如果我在Component2.jsx中删除setTimeout(),或者在Routes.jsx中删除const { token } = provideContext();,问题就消失了.不知道发生了什么.

推荐答案

问题是在ReactTree中声明路由.setToken("Token");ContextProvider中排队状态更新,并触发像Routes这样的消费者重新呈现,当Routes呈现时,它重新声明一个104路由,该路由中断正在处理的任何当前导航操作.

将路由outside声明为ReactTree:

import { RouterProvider, createBrowserRouter } from "react-router-dom";
import { provideContext } from "./provider/ContextProvider";
import Component1 from "./pages/Component1";
import Component2 from "./pages/Component2";

const router = createBrowserRouter([
  {
    path: "/Component2",
    element: <Component2 />,
  },
  {
    path: "/Component1",
    element: <Component1 />,
  },
]);

const Routes = () => {
  const { token } = provideContext();

  return <RouterProvider router={router} />;
};

export default Routes;

或者记住路由,这样当上下文状态更新时,它不会在每个渲染周期重新声明:

import { useMemo } from "react";
import { RouterProvider, createBrowserRouter } from "react-router-dom";
import { provideContext } from "./provider/ContextProvider";
import Component1 from "./pages/Component1";
import Component2 from "./pages/Component2";

const Routes = () => {
  const { token } = provideContext();

  const router = useMemo(() =>
    createBrowserRouter([
      {
        path: "/Component2",
        element: <Component2 />,
      },
      {
        path: "/Component1",
        element: <Component1 />,
      },
    ]), [] // <-- add any required dependencies here
  );

  return <RouterProvider router={router} />;
};

export default Routes;

你真的不需要使用setTimeout来发出导航操作.从Component2中删除setTimeout.

import { useNavigate } from "react-router-dom";
import { provideContext } from "../provider/ContextProvider";

const Component2 = () => {
  const navigate = useNavigate();
  const { setToken } = provideContext();

  const onClick = () => {
    setToken("Token");
    navigate("/Component1");
  };

  return (
    <>
      <button onClick={onClick}>Click me</button>
    </>
  );
};

export default Component2;

Javascript相关问答推荐

React Hooks中useState的同步问题

使用TMS Web Core中的HTML模板中的参数调用过程

有条件的悲剧

按下同意按钮与 puppeteer 师

Redux查询多个数据库Api reducerPath&

Msgraph用户邀请自定义邮箱模板

如何在模块层面提供服务?

如何从html元素创建树 struct ?

使用Promise.All并发解决时,每个promise 的线性时间增加?

在使用位板时,如何在Java脚本中判断Connect 4板中中柱的对称性?

在css中放置所需 colored颜色 以填充图像的透明区域

如何在 Select 文本时停止Click事件?

JavaScript:如果字符串不是A或B,则

如何正确地在ComponentWillUnmount中卸载状态以避免内存泄漏?

需要RTK-在ReactJS中查询多个组件的Mutations 数据

material UI自动完成全宽

使用jQuery每隔几秒钟突出显示列表中的不同单词

如何为两条动态路由创建一个页面?

单击时同时 Select 和展开可访问的行

使用JavaScript或PHP从div ID值创建锚标记和链接