'React - Rerender a class component after the window pathname change
Greeting guys, I have an issue with a class component (that handle a list), the first time I mount the component works without any issue showcasing the expected values, unfortunately when I change the pathname while inside the class component it doesn't updated.
class Servicelist extends React.Component{
constructor({path}) {
super();
this.path = {path}
this.state = {
services : [{
title : 'Brand & Digital',
description : `Lorem ipsum dolor sit amet conse ctetur adipiscing elit`,
image : iservice1,
details: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.',
cost: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.',
additional: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.',
link : '/services/brand_&_digital',
id : 0
},
{
title : 'Graphic Design',
description : 'Lorem ipsum dolor sit amet conse ctetur adipiscing elit',
image : iservice2,
details: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.',
cost: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.',
additional: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.',
link : '/services/graphic_design',
id : 1
},
{
title : 'Advertising',
description : 'Lorem ipsum dolor sit amet conse ctetur adipiscing elit',
image : iservice3,
details: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.',
cost: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.',
additional: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.',
link : '/services/advertising',
id : 2
},
{
title : 'Visual Identity',
description : 'Lorem ipsum dolor sit amet conse ctetur adipiscing elit',
image : iservice4,
details: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.',
cost: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.',
additional: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.',
link : '/services/visual_identity',
id : 3
}]
}
}
render() {
console.log(this.path.path.pathname)
const service = this.state.services.find(service => service.link === this.path.path.pathname)
if (service) {
return <Service {...service} />
}
else{
return null
}
}
}
This component is been render directly into the app component where I have all my sections
function App() {
const pathname = useLocation();
return (
<div className="App">
<Nav/>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/services/:service" element={<Servicelist path={pathname}/>} />
<Route path="/quote" element={<Quote />} />
</Routes>
<Footer/>
</div>
);
}
And the component <Servicelist /> its called by links inside the <Nav/> component like this...
<div className='burgernav-cont'>
<div className='Home-link'>
<Link to="/"> Home </Link>
</div>
<div className='services-links'>
<Link to="/services/brand_&_digital"> Brand & Digital </Link>
<Link to="/services/graphic_design"> Graphic Design </Link>
<Link to="/services/advertising"> Advertising </Link>
<Link to="/services/visual_identity"> Visual Identity </Link>
</div>
<div className='quote-link'>
<Link to="/quote"> Quote </Link>
</div>
<div className='burguer'>
<button onClick={() => setVisible(false)}><Bclose/></button>
</div>
</div>
Solution 1:[1]
If you are using React-Router, You can use the useLocation look.
import { useLocation } from 'react-router-dom';
const { pathname } = useLocation();
Pass pathname through Props
<Component path={pathname}/>
Solution 2:[2]
You wanna make a raw router components by yourself? Ok, That's my:
- Use
componentDidMount. - Use
ref.
Here are codes about kaboom.js that I used.
state = {
canvas: 'canvas',
}
componentDidMount() {
kaboom({
background: [134, 135, 247],
width: 320,
height: 240,
scale: 2,
canvas: this.refs.canvas as any,
})
}
render() {
return (
<>
<Card>
{/* @ts-ignore */}
<canvas width="640" height="640" ref={this.state.canvas}></canvas>
</Card>
</>
)
}
I decide to give you a test codes:
class Test extends Component {
state = {
path: 'path',
}
lazyRoute = (Component: any) => {
return (props: any) => <Component {...props} />
}
componentDidMount() {
const service = this.state.services.find(service => service.link === window.location.pathname)
if (service) {
ReactDom.render(lazyRoute(Service), this.refs.path)
}else {
ReactDom.render(<NotFound />, this.refs.path)
}
}
render() {
<div ref={this.state.path}></div>
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | IQ Digit |
| Solution 2 | wenxuan feng |
