I wanna open a popin inside a route, and I wanna add an hash to the url.
For example before onClick after onClick
Well it works but React Router rerender the whole route.
Am I doing something wrong with React Router ? Let's see my code below (I simplified the things)
index.jsx
I am using BrowserRouter like everybody
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter as Router } from 'react-router-dom';
import App from './App';
const render = Component => {
ReactDOM.render(
<Router>
<Component />
</Router>,
document.getElementById('root')
);
};
render(App);
App.jsx
I am using withRouter because I am gonna need history and location somewhere else
import React from 'react';
import { Route, Switch, withRouter } from 'react-router-dom';
import Header from './components/Header';
import Footer from './components/Footer';
import Home from './views/Home';
const App = ({ ...props }) => {
return (
<Header />
<section>
<Switch>
<Route exact path={"/"} component={() => <Home {...props} />} />
<Route path={"/home"} component={() => <Home {...props} />} />
</Switch>
</section>
<Footer />
);
};
export default withRouter(App);
Home.jsx
unfortunately when I do this.props.history.push({ hash: 'send-me-an-email' })
it will rerender the route component Home, no good
...
render() {
<div>
<button onClick={() => this.props.history.push({ hash: 'send-me-an-email' })}>
Send me and email
</button>
<Popin
isOpened={this.state.isPopinOpened}
handleClose={() => this.props.history.push({ hash: '' })} />
</div>
}
...
How not to make a rerender just because I added a hash to te same url ? Cheers.
I wanna open a popin inside a route, and I wanna add an hash to the url.
For example before onClick https://www.example.com/home
after onClick https://www.example.com/home#send-me-an-email
Well it works but React Router rerender the whole route.
Am I doing something wrong with React Router ? Let's see my code below (I simplified the things)
index.jsx
I am using BrowserRouter like everybody
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter as Router } from 'react-router-dom';
import App from './App';
const render = Component => {
ReactDOM.render(
<Router>
<Component />
</Router>,
document.getElementById('root')
);
};
render(App);
App.jsx
I am using withRouter because I am gonna need history and location somewhere else
import React from 'react';
import { Route, Switch, withRouter } from 'react-router-dom';
import Header from './components/Header';
import Footer from './components/Footer';
import Home from './views/Home';
const App = ({ ...props }) => {
return (
<Header />
<section>
<Switch>
<Route exact path={"/"} component={() => <Home {...props} />} />
<Route path={"/home"} component={() => <Home {...props} />} />
</Switch>
</section>
<Footer />
);
};
export default withRouter(App);
Home.jsx
unfortunately when I do this.props.history.push({ hash: 'send-me-an-email' })
it will rerender the route component Home, no good
...
render() {
<div>
<button onClick={() => this.props.history.push({ hash: 'send-me-an-email' })}>
Send me and email
</button>
<Popin
isOpened={this.state.isPopinOpened}
handleClose={() => this.props.history.push({ hash: '' })} />
</div>
}
...
How not to make a rerender just because I added a hash to te same url ? Cheers.
Share Improve this question edited Aug 2, 2019 at 13:30 Thomas Aumaitre asked Aug 2, 2019 at 13:24 Thomas AumaitreThomas Aumaitre 8071 gold badge8 silver badges18 bronze badges 2- The only solution I can come up is to make use of shouldComponentUpdate and return false when your case matches, with this case you will tell react to not update and it sould not re-render. – Jaime Noel Alvarez Luna Commented Aug 2, 2019 at 13:41
- 1 No you are wrong, this is not the React Class which rerenders, it is the router which detects a new route whith a new hash a closes the old route and reopens the new one lol – Thomas Aumaitre Commented Aug 2, 2019 at 22:22
2 Answers
Reset to default 7Simply rely on vanilla JS:
window.history.pushState("object or string", "Title", "/home#send-me-an-email");
This will add an hash/route without rendering or reloading anything.
I also wanted to add a #hash
to the URL without triggering a re-render.
I simply used the useNavigate()
hook from react-router-dom
v6.
const navigate = useNavigate();
navigate('#my-fancy-hash');
Then, I read this hash with:
const { hash } = useLocation();
One thing to remember is that, at that point, the value of the hash variable would include the # character. When I had to actually use it, I simply stripped it out with:
hash.slice(1)
That should give you the proper value. I hope it helps!