Thomas Aumaitre
Thomas Aumaitre

Reputation: 807

How to add hash to url with React Router without rerendering?

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.

Upvotes: 11

Views: 25292

Answers (2)

Pablo Anaya
Pablo Anaya

Reputation: 341

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!

Upvotes: 6

Mos&#232; Raguzzini
Mos&#232; Raguzzini

Reputation: 15821

Simply 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.

Upvotes: 7

Related Questions