admin管理员组文章数量:1404606
I am starting a new React project and want to use the latest version of React Router. The docs remend using createBrowserRouter
for all web projects. They don't say why it is better than using BrowserRouter
other than it enables some data APIs. Is this the only advantage.
Additionally there is a note in the docs saying
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.
I'm not exactly sure what they mean by outside the React tree
isn't everything in my project in the React tree.
Currently I am implementing my router like this:
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} />
}
This doesn't seem to be outside the React tree but I am not exactly sure what would.
I am starting a new React project and want to use the latest version of React Router. The docs remend using createBrowserRouter
for all web projects. They don't say why it is better than using BrowserRouter
other than it enables some data APIs. Is this the only advantage.
Additionally there is a note in the docs saying
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.
I'm not exactly sure what they mean by outside the React tree
isn't everything in my project in the React tree.
Currently I am implementing my router like this:
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} />
}
This doesn't seem to be outside the React tree but I am not exactly sure what would.
Share Improve this question asked Jan 26, 2024 at 13:57 user11631308user11631308 5- 1 Please ask one question per question, not more than one. – T.J. Crowder Commented Jan 26, 2024 at 14:01
-
Re your second question, "I'm not exactly sure what they mean by outside the React tree...", they mean in code that isn't in a ponent. For instance, code in
main.tsx
that you run prior to callingrender
on the root. (It doesn't have to bemain.tsx
, it just has to be not in a ponent.) – T.J. Crowder Commented Jan 26, 2024 at 14:02 -
@T.J.Crowder how would this be possible when I need my router to be wrapped in the
<AuthenticationTemplate/>
ponent – user11631308 Commented Jan 26, 2024 at 15:16 -
Looking at the documentation, it looks like you use
RouterProvider
there, passing in the router you created outside it, rather than usingRouter
. But I haven't used the latest yet, I was just explaining what they meant in that sentence. – T.J. Crowder Commented Jan 26, 2024 at 15:49 - This is what I love about Stack Overflow: people need help, and people offer help. Thank you for this detailed, precise question. :) (I especially mend you for your transparency around your thought process and assumptions, like "isn't everything in my project in the React tree" -- so helpful for people who want to answer you!) – Lars Kemmann Commented Oct 8, 2024 at 23:08
1 Answer
Reset to default 5Additionally there is a note in the docs saying
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.
I'm not exactly sure what they mean by outside the React tree isn't everything in my project in the React tree.
What this basically means is that is it remended to create the router outside any React ponent such that it is a stable reference.
Example:
const router = createBrowserRouter([
...routes...
]);
function App() {
return <RouterProvider router={router} />;
}
In your implementation the router
is created inside the Router
ponent.
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} />;
}
Router
is rendered by App
.
function App({ msalContext }: AppProps) {
return (
<>
<AuthenticatedTemplate>
<Router currentUser={msalContext.accounts[0]} />
</AuthenticatedTemplate>
</>
);
}
Any time a ponent higher up in the ReactTree than Router
, e.g. AuthenticatedTemplate
or App
, rerenders, their entire sub-ReactTree is rerendered. What this means in Router
now is that the router
will be redeclared and a new reference and this will necessarily remount any of the routed ponents that may be rendered.
Since your router appears to have a dependency on the currentUser
prop a solution here could be to memoize the router
value.
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} />;
}
A better solution however would be to provide the currentUser
or the entire msalContext
value via a React context to your app and decouple if from your routing logic.
Example:
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();
...
};
本文标签: javascriptReact Router using createBrowserRouter vs BrowserRouterStack Overflow
版权声明:本文标题:javascript - React Router using createBrowserRouter vs BrowserRouter - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744844644a2628127.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论