最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to add hash to url with React Router without rerendering? - Stack Overflow

programmeradmin2浏览0评论

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
Add a comment  | 

2 Answers 2

Reset to default 7

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.

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!

发布评论

评论列表(0)

  1. 暂无评论