具备Angular开发背景,如何在React中实现组件编程式路由?
Hey there! Coming from an Angular background, it totally makes sense to seek out a programmatic routing approach similar to router.navigate()—that's the workflow you're familiar with, and it's totally valid to prefer it over declarative components like <Redirect />. Let me walk you through exactly how to do this in React, using the standard React Router library.
主流版本(React Router v6+):使用 useNavigate Hook
React Router v6 overhauled the API a bit, and the go-to tool for programmatic routing is the useNavigate hook. It works very similarly to Angular's router.navigate() and gives you full control over navigation actions.
Here's a quick example in a functional component:
import { useNavigate } from 'react-router-dom'; function MyReactComponent() { // Initialize the navigate function const navigate = useNavigate(); const handleNavigate = () => { // Navigate to an absolute route (just like Angular's router.navigate) navigate('/myroute'); // You can also use relative paths (great for nested routes) // navigate('../another-route'); // Or navigate through history (back/forward) // navigate(-1); // Go back one page // navigate(1); // Go forward one page }; return ( <button onClick={handleNavigate}> Go to My Route </button> ); }
For Class Components (v6)
React Router v6 removed the withRouter HOC that was available in v5, but you can easily create a custom HOC to inject the navigate function into class components:
import { useNavigate, NavigateFunction } from 'react-router-dom'; import React from 'react'; // Custom HOC to add navigate prop to class components const withNavigate = <P extends object>(Component: React.ComponentType<P & { navigate: NavigateFunction }>) => { return (props: P) => { const navigate = useNavigate(); return <Component {...props} navigate={navigate} />; }; }; // Usage in a class component class MyClassComponent extends React.Component { handleRouteChange = () => { this.props.navigate('/myroute'); }; render() { return <button onClick={this.handleRouteChange}>Navigate</button>; } } // Wrap the component with our HOC export default withNavigate(MyClassComponent);
Older Versions (React Router v5): Use useHistory Hook or withRouter
If you're working with React Router v5 (still common in legacy projects), the approach uses the history object instead.
Functional Component (v5)
import { useHistory } from 'react-router-dom'; function MyComponent() { const history = useHistory(); const goToMyRoute = () => { // Push a new route to the history stack history.push('/myroute'); // Replace the current entry (instead of adding a new one) // history.replace('/myroute'); // Go back // history.goBack(); }; return <button onClick={goToMyRoute}>Go to Route</button>; }
Class Component (v5)
Use the built-in withRouter HOC to inject the history prop:
import { withRouter } from 'react-router-dom'; import React from 'react'; class ClassComponent extends React.Component { handleNavigate = () => { this.props.history.push('/myroute'); }; render() { return <button onClick={this.handleNavigate}>Navigate</button>; } } export default withRouter(ClassComponent);
Why You Might Have Missed This
It's easy to overlook at first because React Router's documentation emphasizes declarative routing (like <Redirect />) in some sections, but programmatic routing is absolutely supported and widely used. The key difference from Angular is that React ties this functionality to hooks (or HOCs for class components) rather than a global router instance you inject everywhere.
内容的提问来源于stack exchange,提问作者slipperypete

