React Router 5 的一些API 在 React Router 6 上有时可能找不到,可能会看到如下画面:export ‘useHistory’ was not found in ‘react-router-dom’ …
React Router目前有两个大的版本,即React Router 5、6。React Router 6 在设计上更加简单易用,引入了更直观的 API,同时也弃用了一些不太常用的功能。对于已有的 React Router 5 项目,升级到 React Router 6 会带来一些改动。
通过分析、对比 React Router 5 和 6 之间的使用差异,可以帮助开发者快速掌React Router 5 和 6 的不同地方、差异。对于有 React Router 5 项目经验的开发者来说,理解这些差异有助于更好地过渡到 React Router 6。更好地管理现有项目的升级,提高开发效率和代码质量,并跟上社区的发展趋势。
接下来通过示例代码详细比较一下 React Router 5 和 6 在使用上的主要区别:
- 路由匹配:
- React Router 5 使用
path-to-regexp
作为路径匹配引擎,支持动态路由和正则表达式。 - React Router 6 引入了一种更简单、更直观的匹配机制,默认使用
Matching Patterns
。这种模式更易于理解和使用,不再需要处理复杂的正则表达式。
- React Router 5 使用
例子:
// React Router 5
<Route path="/users/:id" component={UserDetails} />
// React Router 6
<Route path="/users/:userId" element={<UserDetails />} />
- 嵌套路由:
- React Router 5 使用
<Switch>
组件来处理路由匹配,只渲染第一个匹配的组件。 - React Router 6 摒弃了
<Switch>
,改用<Routes>
组件。<Routes>
会渲染所有匹配的组件,更加灵活。
- React Router 5 使用
例子:
// React Router 5
<Switch>
<Route path="/users/:id" component={UserDetails} />
<Route path="/users" component={UserList} />
</Switch>
// React Router 6
<Routes>
<Route path="/users/:userId" element={<UserDetails />} />
<Route path="/users" element={<UserList />} />
</Routes>
- 编程式导航:
- React Router 5 使用
withRouter
高阶组件或this.props.history
来实现编程式导航。 - React Router 6 弃用了
withRouter
,改用useNavigate
hook 来实现编程式导航。
- React Router 5 使用
例子:
// React Router 5
import { withRouter } from 'react-router-dom';
const MyComponent = withRouter(({ history }) => {
const handleClick = () => {
history.push('/users/123');
};
return <button onClick={handleClick}>Go to User Details</button>;
});
// React Router 6
import { useNavigate } from 'react-router-dom';
const MyComponent = () => {
const navigate = useNavigate();
const handleClick = () => {
navigate('/users/123');
};
return <button onClick={handleClick}>Go to User Details</button>;
};
- 参数获取:
- React Router 5 使用
match.params
获取路由参数。 - React Router 6 使用
useParams
hook 获取路由参数。
- React Router 5 使用
例子:
// React Router 5
const UserDetails = ({ match }) => {
const { id } = match.params;
// ...
};
// React Router 6
const UserDetails = () => {
const { userId } = useParams();
// ...
};
- Link 和 NavLink
- React Router 5 中,
<Link>
组件用于构建链接,<NavLink>
组件用于构建导航链接,可以设置activeClassName
或activeStyle
属性。 - React Router 6 中,
<Link>
组件既可以用于构建链接,也可以用于构建导航链接。可以设置className
和style
属性来指定激活状态下的样式。
- React Router 5 中,
// React Router 5
<NavLink to="/home" activeClassName="active">
Home
</NavLink>
// React Router 6
<Link to="/home" className={({ isActive }) => (isActive ? 'active' : '')}>
Home
</Link>
- Redirect 组件
- React Router 5 中使用
<Redirect>
组件进行重定向。 - React Router 6 中使用
<Navigate>
组件进行重定向。
- React Router 5 中使用
// React Router 5
<Redirect from="/old-path" to="/new-path" />
// React Router 6
<Navigate from="/old-path" to="/new-path" />
- 路由配置
- React Router 5 中使用
<Route>
组件配置路由,可以嵌套<Switch>
组件。 - React Router 6 中使用
<Routes>
组件配置路由,不再需要<Switch>
组件。
- React Router 5 中使用
// React Router 5
<Route path="/users">
<Switch>
<Route path="/users/:id" component={UserDetails} />
<Route path="/users" component={UserList} />
</Switch>
</Route>
// React Router 6
<Routes>
<Route path="/users/:userId" element={<UserDetails />} />
<Route path="/users" element={<UserList />} />
</Routes>
- 历史记录管理
- React Router 5 中使用
history
对象管理历史记录。 - React Router 6 中使用
useNavigate
hook 管理历史记录。
- React Router 5 中使用
// React Router 5
const handleClick = () => {
props.history.push('/users/123');
};
// React Router 6
const navigate = useNavigate();
const handleClick = () => {
navigate('/users/123');
};
总的来说,React Router 6 在设计上更加简单易用,引入了更加直观的路由匹配机制和组件结构。同时也弃用了一些不太常用的 API,如 withRouter
,转而使用更加灵活的 hook 来实现功能。对于已有的 React Router 5 项目,升级到 React Router 6 可能需要一些改动,但收益是值得的。