对于“错误:不变式失败:您不应该在<Route>
之外使用<Router>
”有很多问题,但是这一点不同,它仅在使用以下组件时出现:返回<Route>
的库。
我的目的是在私有库中创建一个<GuardedRoute>
组件,我公司的其他人可以使用npm
安装该组件。这个新的组件返回一个<Route>
,但是首先检查谓词的返回值。如果检查失败,则<Route>
将指向某些替代页面组件。一个简单的用例是检查用户是否已通过身份验证。如果是这样,component
中的任何内容都会被渲染;否则,将呈现替代页面组件,即登录屏幕。
如果<GuardedRoute>
组件位于正在使用它的应用程序中的某个位置,则可以正常工作。但是,如果相同的组件位于库中,并且应用import
的{{1}}来自库而不是来自其自己的项目目录结构,那么我得到:
<GuardedRoute>
堆栈跟踪没有太大帮助;最新的相关内容正在Error: Invariant failed: You should not use <Route> outside a <Router>
中的ReactDOM.render()
上抛出。
该库被编译为JS,然后使用index.tsx
安装到应用程序中。
index.tsx
npm i path/to/library/on/my/filesystem
App.tsx
import * as React from 'react';
import ReactDOM from 'react-dom';
import { App } from './App';
import './index.css';
function __init() {
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
}
__init();
PrivateRoute.tsx
import * as React from 'react';
import {
Route,
BrowserRouter,
Switch
} from 'react-router-dom';
import { ReportDirectoryActivity } from 'components/activities/ReportDirectoryActivity/ReportDirectoryActivity';
import { AuthActivity } from 'components/activities/AuthActivity/AuthActivity';
import { LogoutActivity } from 'components/activities/LogoutActivity/LogoutActivity';
import { PrivateRoute } from 'components/shared/PrivateRoute/PrivateRoute';
export const App: React.FC = () => {
return (
<BrowserRouter>
<Switch>
<Route
exact
path="/auth"
component={AuthActivity} />
<Route
exact
path="/logout"
component={LogoutActivity} />
<PrivateRoute
exact
path="/"
component={ReportDirectoryActivity} />
</Switch>
</BrowserRouter>
);
};
GuardedRoute.tsx(位于库中)
import * as React from 'react';
import {
RouteProps,
Redirect
} from 'react-router-dom';
// if this line is changed to refer to an identical component within the app, this works fine
import { GuardedRoute } from 'my-library/GuardedRoute';
export interface IPrivateRouteProps extends RouteProps {}
export const PrivateRoute: React.FC<IPrivateRouteProps> = props => {
// using a pass-through fnGuard() just to test
return (
<GuardedRoute
{...props}
fnGuard={() => true}
elFailure={(
<Redirect to="/auth" />
)} />
);
};
答案 0 :(得分:0)
库需要在其Webpack配置中指定可以从外部依赖项中使用react-router-dom
。
将以下内容添加到您的库Webpack配置中
externals: {
'react': 'react',
'react-dom': 'react-dom',
'react-router-dom': 'react-router-dom' // Add this too apart from react
},
答案 1 :(得分:0)
我的猜测是您的库代码抛出错误,因为它没有将路由器组件视为父组件。
也许您可以创建一个GuardedComponent
来包装传递的Component
而不是扩展路线?这段代码未经测试,只是出于一般目的。
interface IGuardedComponentProps {
children: React.ReactNode
fnGuard: () => boolean;
elFailure: JSX.Element;
}
export const GuardedComponent: React.FC<IGuardedComponentProps> = props => {
const { children, fnGuard, elFailure } = props;
return (
<>{fnGuard() ? elFailure : children}</>
);
};
然后您将使用它
<Route
exact
path="/"
>
<GuardedComponent
fnGuard={() => true}
elFailure={(
<Redirect to="/auth" />
)} />
>
<ReportDirectoryActivity />
</GuardedComponent>
</Route>
答案 2 :(得分:-2)
嘿,哈哈。为什么不阅读React Route库的文档?其中写道,您应该在内部使用<Route>
组件 <Router>
。
最简单的方法是将App
组件包装到Router
文件中的index.tsx
中:
import * as React from 'react';
import ReactDOM from 'react-dom';
import { App } from './App';
import './index.css';
function __init() {
ReactDOM.render(
<React.StrictMode>
<Router>
<App />
</Router>
</React.StrictMode>,
document.getElementById('root')
);
}
__init();