我们有基于遗留类的代码,我们正在尝试将其迁移到版本 6 的最新 React 路由器。在迁移过程中,我们收到此错误:
模块“react-router-dom”没有导出成员“RouteComponentProps”
我们添加了
withRouter
包装器以添加遗留支持。
import { useLocation, useNavigate, useParams } from "react-router-dom";
function withRouter(Component) {
function ComponentWithRouterProp(props) {
let location = useLocation();
let navigate = useNavigate();
let params = useParams();
return <Component {...props} router={{ location, navigate, params }} />;
}
return ComponentWithRouterProp;
}
export default withRouter;
我们基于类的组件如下所示:
import { Route, RouteComponentProps, Routes } from "react-router-dom";
class App extends React.Component<{} & RouteComponentProps<{}>, IState> {
constructor(props: RouteComponentProps<{}>) {
super(props);
this.state = {
prop1: null
};
}
componentDidMount() {
if (this.props.location.pathname === "/test") {
window.location.reload();
}
};
render() {
return (
<Routes>
<Route path="/test" element={<Test />} />
</Routes>
)
}
}
export default withRouter(App);
如何解决这个问题?
react-router-dom@6
不导出任何 RouteComponentProps
类型。事实上,RRD6 完全取消了路线属性,以前的 location
、navigate
和 params
值现在分别使用 useLocation
、useNavigate
和 useParams
访问。withRouter
高阶组件不会注入“路由参数”,它会注入一个名为router
的具有“路由参数”的道具。在大多数情况下,“我如何解决这个问题?”的答案就是将Class组件转换为Function组件,直接使用hooks。为了解决遗留代码的问题,您必须自己手动输入“route props”。
示例:
import {
Location,
NavigateFunction,
Params,
useLocation,
useNavigate,
useParams,
} from "react-router-dom";
export interface RouterProps {
location: Location;
navigate: NavigateFunction;
params: Params;
}
export interface WithRouter {
router: RouterProps;
}
function withRouter(Component: any) {
function ComponentWithRouterProp(props: any) {
const location = useLocation();
const navigate = useNavigate();
const params = useParams();
return <Component {...props} router={{ location, navigate, params }} />;
}
return ComponentWithRouterProp;
}
export default withRouter;
interface IState {
prop1: .....
}
interface IProps extends WithRouter {
.....
}
class App extends React.Component<IProps, IState> {
constructor(props: IProps) {
super(props);
this.state = {
prop1: null
};
}
componentDidMount() {
if (this.props.router.location.pathname === "/test") {
// ...
}
}
render() {
return (
<Routes>
<Route path="/test" element={<Test />} />
</Routes>
);
}
}
export default withRouter(App);
注意:自 2019 年 2 月发布 React hooks 以来,React 类组件已被有效弃用。现在已经是 2024 年了,你真的应该尝试使用 Function 组件编写现代 React。当使用像 react-router-dom
这样专门使用 React hooks 的新版本库时尤其如此。