📜  反应路由器历史未定义 - Javascript(1)

📅  最后修改于: 2023-12-03 15:22:54.091000             🧑  作者: Mango

反应路由器历史未定义 - Javascript

当使用React Router v5或更早版本时,可能会遇到以下错误:

Warning: You cannot change <Router history>; it will be ignored

这个警告通常发生在React组件中定义了一个新的浏览器历史记录(history)对象,而不是使用Router的默认历史记录。

在React Router v6中,使用新的@router包,警告已经不再存在,反应(React)路由器的设计也完全改变了,这个问题不复存在。如果你是在使用React Router v5或更早的版本,则可以按照以下步骤解决该问题。

问题

React Router v5和较早版本的Router组件依赖于一个全局的历史记录(history)对象,这个对象是由包含Router组件的父组件创建的。这种方法确保了整个应用程序都使用相同的历史记录,从而保证路由功能的正确性。

如果在组件中创建了一个新的历史记录对象,则将更改React Router的默认历史记录,这可能会导致路由组件无法正常工作。

解决方法
1. 从父组件传递history属性

在父组件中创建一个历史记录对象,并将其传递给Router组件。这个历史记录对象可以使用react-router-dom中的createBrowserHistory函数创建。然后在Router组件中,将history属性设置为传递的历史记录对象:

import { Router } from 'react-router-dom';
import { createBrowserHistory } from 'history';

const history = createBrowserHistory();

function App() {
  return (
    <Router history={history}>
      {/* your routes here */}
    </Router>
  );
}
2. 使用withRouter高阶组件

withRouter是一个高阶组件,它将React组件包装在另一个组件中,并将路由相关的属性(如location、history和match)作为props传递给被包装组件。使用withRouter高阶组件可以使组件访问React Router的默认历史记录对象。例如:

import { withRouter } from 'react-router-dom';

class MyComponent extends React.Component {
  // ...
}

export default withRouter(MyComponent);

高阶组件包装后的组件将会接收到withRouter提供的props:

  • history: the history object for the router
  • location: the current location of the router
  • match: the matching information for the route
3. 使用useHistory React Hook

useHistory是一种React Hook,它提供了默认历史记录对象的访问。它返回一个包含history对象的数组,并且可以在函数组件和自定义hook中使用。例如:

import { useHistory } from 'react-router-dom';

function MyComponent() {
  const history = useHistory();

  // Use `history` object here

  return (...);
}
结论

在React Router v6中,不再需要担心该问题,因为新的@router包不再依赖全局浏览器历史记录对象,而是使用一个新的基于React状态的历史记录对象来管理路由。但是在使用React Router v5及早期的版本时,应该采取上述措施来避免意外更改React Router的默认历史记录对象。