[英]React + MSAL + React Router 6.4.1 (latest version) loader feature question
亲爱的 React 开发人员。
当您想使用新的加载器功能时,有人可以解释或展示在当前最新版本 6.4.1 中将 MSAL 与 React Router 结合使用时最好的方法是什么?
基于您可以在此处阅读的新加载程序功能:
“每条路由都可以定义一个“加载器”function,以便在渲染之前向路由元素提供数据。”
https://reactrouter.com/en/main/route/loader
这个问题出现在我身上,因为我在这里缺乏想象力......我记得访问 msal 实例的唯一方法是使用 MSAL 库在 MsalProvider 内的组件上提供的挂钩。 但是,新的加载程序功能依赖于普通的 function,我无法使用钩子或访问任何应用程序 state。
任何帮助都将受到欢迎。 提前致谢。
为了在下面提供一些背景信息,我分享了一些我的应用程序代码。
在我的 UserEditScreen.tsx 中:
// UserEditScreen component definition
....
// loader definition outside UserEditScreen component
export const loader = ({ request, params }: LoaderFunctionArgs) => {
...
// some more code to clarify my need on the msal instance inside the loader
const request = {
account: msalInstance.getActiveAccount(),
scopes: scopes
}
const accessToken = await msalInstance.acquireTokenSilent(request)
.then(response => response.accessToken)
.catch(error => {
console.error(error);
})
// then with the accessToken I can just use made
// a javascript fetch request to my secured endpoint in azure
...
}
在我的 app.tsx
type AppProps = {
msalInstance: PublicClientApplication;
}
const router = createBrowserRouter(createRoutesFromElements(
<Route path="/" errorElement={<GlobalError />}>
...
<Route path="/administration" element={
<AuthenticatedScreen>
<AdministrationScreen />
</AuthenticatedScreen>
}>
<Route path='users' element={<UsersScreen />} />
<Route path='users/new' element={<UserNewScreen />} />
<Route path='users/:id/edit'
element={<UserEditScreen />}
loader={userLoader}
errorElement={<UserEditError />}
/>
</Route>
...
</Route>
));
function App({ msalInstance }: AppProps) {
return (
<MsalProvider instance={msalInstance}>
<RouterProvider router={router} />
</MsalProvider>
);
}
export default App;
在我的 index.tsx
const msalInstance = new PublicClientApplication(msalConfig);
const accounts = msalInstance.getAllAccounts();
if (accounts.length > 0) {
msalInstance.setActiveAccount(accounts[0]);
}
msalInstance.addEventCallback((event: EventMessage) => {
if (event.eventType === EventType.LOGIN_SUCCESS && event.payload) {
const payload = event.payload as AuthenticationResult;
const account = payload.account;
msalInstance.setActiveAccount(account);
}
});
const root = ReactDOM.createRoot(
document.getElementById('root') as HTMLElement
);
root.render(
<React.StrictMode>
<App msalInstance={msalInstance} />
</React.StrictMode>
);
您可以将其转换为 function,而不是创建路由器组件,该组件将msalInstance
作为参数在 scope 中关闭它并返回配置的路由器。
例子:
应用程序
type AppProps = {
msalInstance: PublicClientApplication;
}
interface CreateRouter {
msalInstance: PublicClientApplication;
}
const createRouter = ({ msalInstance }: CreateRouter) => createBrowserRouter(
createRoutesFromElements(
<Route path="/" errorElement={<GlobalError />}>
...
<Route path="/administration" element={
<AuthenticatedScreen>
<AdministrationScreen />
</AuthenticatedScreen>
}>
<Route path='users' element={<UsersScreen />} />
<Route path='users/new' element={<UserNewScreen />} />
<Route path='users/:id/edit'
element={<UserEditScreen />}
loader={userLoader(msalInstance)}
errorElement={<UserEditError />}
/>
</Route>
...
</Route>
)
);
...
function App({ msalInstance }: AppProps) {
return (
<MsalProvider instance={msalInstance}>
<RouterProvider router={createRouter({ msalInstance })} />
</MsalProvider>
);
}
export default App;
用户编辑屏幕
Similarly the loader
function can be updated to a curried function that takes the msalInstance
object as an argument and returns the loader function with the msalInstance
object closed over in scope.
// loader definition outside UserEditScreen component
export const loader = (msalInstance: PublicClientApplication) =>
({ request, params }: LoaderFunctionArgs) => {
...
// some more code to clarify my need on the msal instance inside the loader
const request = {
account: msalInstance.getActiveAccount(),
scopes: scopes
}
const accessToken = await msalInstance.acquireTokenSilent(request)
.then(response => response.accessToken)
.catch(error => {
console.error(error);
})
// then with the accessToken I can just use made
// a javascript fetch request to my secured endpoint in azure
...
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.