我正在一点一点地将一个 AngularJS 应用程序迁移到 React,我想要一个自定义的RouterLinkReact 组件来检查是否react-router在上下文中,以便它可以使用history,如果没有,则回退到使用 good old window.location。但是我在react-router的文档中看不到任何检查方法。
我尝试使用withRouter但它在不在上下文中时抛出并且ErrorBoundary似乎没有捕获错误。
有谁知道我该怎么做?
我正在一点一点地将一个 AngularJS 应用程序迁移到 React,我想要一个自定义的RouterLinkReact 组件来检查是否react-router在上下文中,以便它可以使用history,如果没有,则回退到使用 good old window.location。但是我在react-router的文档中看不到任何检查方法。
我尝试使用withRouter但它在不在上下文中时抛出并且ErrorBoundary似乎没有捕获错误。
有谁知道我该怎么做?
react-router包中公开了路由器上下文,即__RouterContext,通过使用它您可以检查路由器是否可用:
import React, { useContext } from 'react';
import { __RouterContext } from 'react-router';
const MyComponent = (props) => {
const router = useContext(__RouterContext);
if (router) {
// Router context is avaible
} else {
// Use window.location as router context is not availble in this component
}
return <SomeOtherComponent />
}
只需将钩子包裹在一个try/catch:
const {useState, useEffect, Fragment} = React;
const {useLocation, MemoryRouter} = ReactRouter;
const Cmp = () => {
let loc;
try {
loc = useLocation();
} catch (err) {
return (
<div>No Router Available</div>
);
}
return (
<div>Hello I can see {loc.pathname}</div>
);
};
const App1 = () => {
return (
<Cmp/>
);
};
const App2 = () => {
return (
<MemoryRouter>
<Cmp/>
</MemoryRouter>
);
};
ReactDOM.render(<App1 />, document.getElementById("app1"));
ReactDOM.render(<App2 />, document.getElementById("app2"));
<script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/react-router@5.1.2/umd/react-router.js"></script>
<div id="app1"></div>
<div id="app2"></div>