这是我运行应用程序后遇到的错误。
./node_modules/@okta/okta-react/bundles/okta-react.esm.js 284:14-27 中出现错误
在“react-router-dom”中找不到导出“useRouteMatch”(导入为“useRouteMatch”)(可能导出:BrowserRouter、HashRouter、Link、MemoryRouter、NavLink、Navigate、Outlet、Route、Router、Routes、UNSAFE_LocationContext、UNSAFE_NavigationContext 、UNSAFE_RouteContext、createRoutesFromChildren、createSearchParams、generatePath、matchPath、matchRoutes、renderMatches、resolvePath、unstable_HistoryRouter、useHref、useInRouterContext、useLinkClickHandler、useLocation、useMatch、useNavigate、useNavigationType、useOutlet、useOutletContext、useParams、useResolvedPath、useRoutes、useSearchParams)
这是我的 Index.tsx 文件中的代码。
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
import "mdb-react-ui-kit/dist/css/mdb.min.css";
import { Security } from "@okta/okta-react";
import { OktaAuth } from "@okta/okta-auth-js";
const config = {
clientId: "*********************",
issuer: "https://****************/oauth2/default",
redirectUri: "http://localhost:3000/login/callback",
scopes: ["openid", "profile", "email"],
pkce: true,
};
const oktaAuth = new OktaAuth(config);
const restoreOriginalUri = () => {
// Callback function to restore URI during login
};
ReactDOM.render(
<React.StrictMode>
<Security oktaAuth={oktaAuth} restoreOriginalUri={restoreOriginalUri}>
<App />
</Security>
</React.StrictMode>,
document.getElementById("root")
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more:
reportWebVitals();
我凭直觉假设你使用比 v5 更新的 React-router 版本。
根据https://github.com/okta/okta-react/issues/187
@okta/okta-react currently only supports react-router v5. We are currently investigating v6 support
我遇到了同样的问题,但这是我的解决方法。
首先,这不是官方方式,因为 okta 仍然不支持react-router v6。 但通过一些技巧,就可以让 okta-react 与 React-router v6 一起运行。
首先,您必须在 index.js 文件中添加新的
<BrowserRouter>
标签:
index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import { BrowserRouter } from 'react-router-dom';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>
);
完成此操作后,您必须为安全路由创建一个新组件。这个组件非常简单,因为它只是检查用户是否登录。如果没有登录,您将被重定向到登录页面。 该检查将通过 okta-react 库提供的钩子完成。我们稍后将设置库。
PrivateRoutes.js
import { Outlet, Navigate } from "react-router-dom";
import { useOktaAuth } from '@okta/okta-react';
const PrivateRoutes = () => {
const { authState } = useOktaAuth();
if(!authState) {
return <div>Loading...</div>;
}
return (
authState.isAuthenticated ? <Outlet /> : <Navigate to="/login"/>
);
}
export default PrivateRoutes;
最后一部分是App.js文件。在此文件中,我们将设置 okta-react 库并配置私有和公共路由。从reacr-router v5到react-router v6的更新中,很多事情发生了变化。如果您想知道发生了什么变化以及它是如何工作的,我推荐以下文章:
App.js 文件中重要的是,
<Security>
标签包裹在 <Routes>
标签周围。由于 <Routes>
标签只能有 <Route>
子级(可以嵌套,但它们必须是
<Route>
-标签)。以下视频是有关 React-router v6 中私有路由的一个很好的教程(为本文提供了基础):OktaAuth-Component 的配置就像 okta 的官方指南所描述的那样。 React-router v5 中的 useHistory()-Stuff 已更新为 React-router v6 中的 useNavigate()。 这是我的完整 App.js 文件:
App.js
import { Route, Routes, useNavigate } from 'react-router-dom';
import PrivateRoutes from './components/PrivateRoutes';
import { OktaAuth, toRelativeUrl } from '@okta/okta-auth-js';
import { LoginCallback, Security } from '@okta/okta-react';
import Test from './pages/Test';
import Home from './pages/Home';
import Login from './pages/Login';
import './App.css';
const oktaAuth = new OktaAuth({
issuer: process.env.REACT_APP_OKTA_ISSUER,
clientId: process.env.REACT_APP_OKTA_CLIENT_ID,
redirectUri: window.location.origin + '/login/callback'
});
function App() {
const navigate = useNavigate();
const restoreOriginalUri = async (_oktaAuth, originalUri) => {
navigate(toRelativeUrl(originalUri || '/login', window.location.origin), {replace: true});
}
return (
<div className="App">
<Security oktaAuth={oktaAuth} restoreOriginalUri={restoreOriginalUri} >
<Routes>
<Route element={ <PrivateRoutes />}>
{/* PRIVATE_ROUTES_BEGIN */}
<Route element={ <Home /> } path="/" exact/>
<Route element={ <Test /> } path="/test"/>
{/* PRIVATE_ROUTES_END */}
</Route>
<Route element={ <Login /> } path="/login"/>
<Route element={ <LoginCallback />} path="/login/callback"/>
</Routes>
</Security>
</div>
);
}
export default App;
请记住,react-router v6 中新的
Route
元素采用 HTML-Tags,而不仅仅是组件的“名称”我希望这有点用。同样,这不是官方方式,但我对此主题做了一些测试,它对我来说效果很好。我还是希望okta能在某个时候发布官方的react-router v6支持:)