Reputation: 3443
Failed to compile. Attempted import error: 'withRouter' is not exported from 'react-router-dom'.
My code like, also I have installed react-router-dom
an react-route and I have respin the app 10 time now
import React from 'react';
import {withRouter} from 'react-router-dom';
import './menu-item.scss';
const MenuItem = ({ title, imageUrl, size, history }) => (
<div className={`${size} menu-item`}>
<div
className='background-image'
style={{
backgroundImage: `url(${imageUrl})`,
}}
/>
<div className='content'>
<h1 className='title'>{title.toUpperCase()}</h1>
<span className='subtitle'>SHOP NOW</span>
</div>
</div>
);
export default withRouter(MenuItem);
Upvotes: 8
Views: 25870
Reputation: 202618
If you accidentally installed react-router-dom
v6 then the withRouter
HOC no longer exists. Either revert back to v5 (run npm install -s react-router-dom@5
), or roll your own custom withRouter
HOC to inject the props you need or convert the components to function components and use the React hooks.
withRouter
Higher Order ComponentFrom the FAQ: What happened to withRouter I need it
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; }
There is now also no longer a history
object to use, it was replaced by a navigate
function accessed via the useNavigate
hook. It's not clear where history
was being used previously, but if you need to imperatively navigate the following is how you access the navigation. If staying with v6 then the following is how to access the navigate
function.
import React from 'react';
import { useNavigate } from 'react-router-dom';
import './menu-item.scss';
const MenuItem = ({ title, imageUrl, size }) => {
const navigate = useNavigate();
// navigate("/targetPath")
return (
<div className={`${size} menu-item`}>
<div
className='background-image'
style={{
backgroundImage: `url(${imageUrl})`,
}}
/>
<div className='content'>
<h1 className='title'>{title.toUpperCase()}</h1>
<span className='subtitle'>SHOP NOW</span>
</div>
</div>
)
};
export default MenuItem;
Upvotes: 14
Reputation: 11
in menu-item.component.jsx you can use the useNavigate just like this one
import React from "react";
import { useNavigate } from "react-router-dom";
import "./menu-item.styles.scss";
const MenuItem = ({ title, imageUrl, size, history, linkUrl, match }) => {
let navigate = useNavigate();
return (
<div className={`${size} menu-item`} onClick={() => navigate(`${linkUrl}`)}>
<div
className="background-image"
style={{
backgroundImage: `url(${imageUrl})`,
}}
></div>
<div className="content">
<h1 className="title">{title.toUpperCase()}</h1>
<span className="subtitle">SHOP NOW</span>
</div>
</div>
);
};
export default MenuItem;
Also, in App.js you should import Routes and Route from react-router-dom and make your code like this:
import React from "react";
import { Routes, Route } from "react-router-dom";
import "./App.css";
import HomePage from "./pages/homepage/homepage.component";
const HatsPage = () => (
<div>
<h1>Hats page</h1>
</div>
);
function App() {
return (
<div>
<Routes>
<Route exact path="/" element={<HomePage />} />
<Route path="/hats" element={<HatsPage />} />
</Routes>
</div>
);
}
export default App;
As for me, this works.
Upvotes: 1
Reputation: 3443
thanks to Drew Reese -great shout-, and similar to Switch ( will throw the same error ) here is the downgrade command, just make sure you are in the right directory
npm install [email protected]
Upvotes: 2
Reputation: 41
You can use useLocation hook and destructure 'pathname' property from it to make the navigated link in the onClick() function dynamic.
Here's a sample of the code that worked for me:
import React from "react";
import { useLocation, useNavigate } from "react-router-dom";
import "./menu-item.styles.scss";
const MenuItem = ({ title, imageUrl, size, linkUrl, match }) => {
let navigate = useNavigate();
// destructured "pathname" property from useLocation()
let { pathname } = useLocation();
// consoloe.log(pathname)
return (
<div className={`${size} menu-item`} onClick={() => navigate(`${pathname}${linkUrl}`)}>
<div
className="background-image"
style={{
backgroundImage: `url(${imageUrl})`,
}}
/>
<div className="content">
<h1 className="title">{title.toUpperCase()}</h1>
<span className="subtitle">SHOP NOW</span>
</div>
</div>
);
};
export default MenuItem;
Upvotes: 2
Reputation: 1
try this it worked for me
import React from "react";
import { useNavigate } from "react-router-dom";
import "./menu-item.styles.scss";
const MenuItem = ({ title, imageUrl, size, history, linkUrl, match }) => {
const navigate = useNavigate();
return (
<div className={`${size} menu-item`} onClick={() => navigate(`hats`)}>
<div
className="background-image"
style={{
backgroundImage: `url(${imageUrl})`,
}}
></div>
<div className="content">
<h1 className="title">{title.toUpperCase()}</h1>
<span className="subtitle">SHOP NOW</span>
</div>
</div>
);
};
export default MenuItem;
Upvotes: 0