我正在启动一个新的react 项目,并希望使用最新版本的react 路由.文档建议对所有Web项目使用createBrowserRouter.他们没有说为什么它比使用BrowserRouter更好,只是启用了一些数据API.这是唯一的优势吗.

此外,文档中有一个注释,

Due to the decoupling of fetching and rendering in the design of the data APIs, you should create your router outside of the React tree with a statically defined set of routes. For more information on this design, please see the Remixing React Router blog post and the When to Fetch conference talk.

我不太确定他们所说的outside the React tree并不是我在Reaction树中的项目的全部.

目前我是这样实现我的路由的:

Main.tsx

ReactDOM.createRoot(document.getElementById('root')!).render(
  <GenReMsal>
    <React.StrictMode>
      <App />
    </React.StrictMode>
  </GenReMsal>
)

App.js

function App({ msalContext }: AppProps) {
  return (
    <>
      <AuthenticatedTemplate>
        <Router currentUser={msalContext.accounts[0]} />
      </AuthenticatedTemplate>
    </>
  )
}

Router.js

function Router({ currentUser }: Props) {
  const userInfo = { name: currentUser.name }

  const router = createBrowserRouter([
    {
      path: '/:appTypeId?',
      element: <AppLayout currentUser={userInfo} />,
      loader: defaulNewAPIs,
      children: [
        {
          index: true,
          element: <ReferralDetails status="new" />,
        },
      ],
    },
  ])

  return <RouterProvider router={router} />
}

这似乎不在react 树之外,但我不完全确定什么会.

推荐答案

此外,文件中还有一条注解说

由于在设计中提取和呈现的解耦 数据API,您应该在Reaction树之外创建路由 具有静态定义的一组路由.有关这方面的更多信息 设计,请参阅重新混合react 路由的博客文章和何时 找人谈一谈.

我不太确定他们所说的React树外是什么意思 我的项目中的所有内容都在React树中.

这基本上意味着建议创建路由100的任何react 组件,以便它是稳定的引用.

示例:

const router = createBrowserRouter([
  ...routes...
]);

function App() {
  return <RouterProvider router={router} />;
}

在您的实现中,router被创建102,Router组件.

function Router({ currentUser }: Props) {
  const userInfo = { name: currentUser.name }

  const router = createBrowserRouter([
    {
      path: '/:appTypeId?',
      element: <AppLayout currentUser={userInfo} />,
      loader: defaulNewAPIs,
      children: [
        {
          index: true,
          element: <ReferralDetails status="new" />,
        },
      ],
    },
  ]);

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

RouterApp渲染.

function App({ msalContext }: AppProps) {
  return (
    <>
      <AuthenticatedTemplate>
        <Router currentUser={msalContext.accounts[0]} />
      </AuthenticatedTemplate>
    </>
  );
}

任何时候,当react 树中高于Router的组件(例如AuthenticatedTemplateApp)被重新呈现时,它们的整个子react 树被重新呈现.这在Router中意味着router将被重新声明和新的引用,并且这将105重新挂载可以呈现的任何被布线的组件.

由于您的路由似乎对currentUser prop有依赖性,因此这里的解决方案可能是记住router值.

function Router({ currentUser }: Props) {
  const router = React.useMemo(() => {
    return createBrowserRouter([
      {
        path: '/:appTypeId?',
        element: <AppLayout currentUser={{ name: currentUser.name }} />,
        loader: defaulNewAPIs,
        children: [
          {
            index: true,
            element: <ReferralDetails status="new" />,
          },
        ],
      },
    ]);
  }, [currentUser]);

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

然而,一个更好的解决方案是通过Reaction上下文向您的应用程序提供currentUser或整个msalContext值,并将IF与您的路由逻辑分离.

示例:

const MsalContext = React.createContext( .... );

const useMsalContext = () => React.useContext();

const MsalContextProvider = ({ children, msalContext }) => {
  return (
    <MsalContext.Provider value={msalContext}>
      {children}
    </MsalContext.Provider>
  );
};
function App({ msalContext }: AppProps) {
  return (
    <MsalContextProvider msalContext={msalContext}>
      <AuthenticatedTemplate>
        <Router />
      </AuthenticatedTemplate>
    </MsalContextProvider>
  )
}
const router = createBrowserRouter([
  {
    path: '/:appTypeId?',
    element: <AppLayout />,
    loader: defaulNewAPIs,
    children: [
      {
        index: true,
        element: <ReferralDetails status="new" />,
      },
    ],
  },
]);

function Router() {
  return <RouterProvider router={router} />;
}
const AppLayout = () => {
  const {
    accounts: [
      { name } // msalContext.accounts[0].name -> name
    ]
  } = useMsalContext();

  ...
};

Javascript相关问答推荐

如何访问Json返回的ASP.NET Core 6中的导航图像属性

yarn安装一个本地npm包,以便本地包使用main项目的node_modules(ckeditor-duplicated-modules错误)

了解Node.js中的EventEums和浏览器中的addEventEums之间的关系

togglePopover()不打开但不关闭原生HTML popover'

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

函数返回与输入对象具有相同键的对象

未捕获错误:[]:getActivePinia()被调用,但没有活动Pinia.🍍""在调用app.use(pinia)之前,您是否try 使用store ?""

简单的PayPal按钮集成导致404错误

还原器未正确更新状态

类构造函数不能在没有用With Router包装的情况下调用

try 使用PM2在AWS ubuntu服务器上运行 node 进程时出错

我想将Sitecore搜索面过滤器从多个转换为单个

基于产品ID更新条带产品图像的JavaScript命中错误

FileReader()不能处理Firefox和GiB文件

为列表中的项目设置动画

如何通过Axios在GraphQL查询中发送数组

为什么我的Navbar.css没有显示在本地主机页面上?

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

如何使pdf.js上的文本呈现为可选?

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