How I migrated to useNavigate from withRouter in v6 of React-Router
And save yourself time and embarrassment.
In moving to a newer version of react-router, I had to ditch wrapping my connect function with withRouter and ditch the useHistory to create a history stack, it took a bit of documentation searching and decided to move on to useNavigate on clicks instead of creating a whole new Link tag. The reason I didn't want to use the imported Link tag is that I hear its considered bad practice to wrap an anchor tag around a button tag in the HTML5 spec W3C documents:
Content model: Transparent, but there must be no interactive content descendant. The a element may be wrapped around entire paragraphs, lists, tables, and so forth, even entire sections, so long as there is no interactive content within (e.g. buttons or other links).
The way I introduced it is I switched one component code, my old way:
import { withRouter } from 'react-router-dom';
const StoreProduct = ({ products, history, dispatch, id }) => (
<div className='product-overview'>
<div className='product-details'>
...
</div>
<CustomButton
onClick={() => {
history.push('/products/{id}')
}}
>
...
</CustomButton>
</div>
)
...
export default withRouter(connect(mapStateToProps)(StoreProduct));
So to skip the whole mess and to move away from the former mentioned, I transitioned to a useNavigate, and example from my current project :
import { useNavigate } from "react-router";
const CartDropdown = ({ cartItems }) => {
const navigate = useNavigate();
return (
<div className="cart-dropdown">
<div className="cart-items">
...
</div>
<CustomButton onClick={() => navigate("checkout")}>
GO TO CHECKOUT
</CustomButton>
</div>
);
};
...
export default connect(mapStateToProps)(CartDropdown);
The useNavigate is more in tune with hooks now, though the change is subtle. It still took me a while to my embarrassment. It was a learning moment to consult the documentation first.