Link component update browser history when location is the same












2















I used react router v 4.3.1
When i click on home page link many times, each click creates a new history item. Home page is re-rendered every time. Now your browser navigation is broken (back/forward buttons are not working as expected).



import React from 'react';
import { render } from 'react-dom';
import { BrowserRouter as Router, Route, Link } from 'react-router-dom';

const Example = () => (
<Router>
<div>
<ul>
<li><Link to="/">Home</Link></li>
<li><Link to="/">Home 1</Link></li>
<li><Link to="/">Home 2</Link></li>
<li><Link to="/about">About</Link></li>
<li><Link to="/topics">Topics</Link></li>
</ul>

<hr />

<Route exact path="/" render={()=><p>Home</p>} />
<Route path="/about" render={()=><p>about</p>} />
<Route path="/topics" render={()=><p>topics</p>} />
</div>
</Router>
);

render(<Example />, document.body);


Help, how to fix this?










share|improve this question





























    2















    I used react router v 4.3.1
    When i click on home page link many times, each click creates a new history item. Home page is re-rendered every time. Now your browser navigation is broken (back/forward buttons are not working as expected).



    import React from 'react';
    import { render } from 'react-dom';
    import { BrowserRouter as Router, Route, Link } from 'react-router-dom';

    const Example = () => (
    <Router>
    <div>
    <ul>
    <li><Link to="/">Home</Link></li>
    <li><Link to="/">Home 1</Link></li>
    <li><Link to="/">Home 2</Link></li>
    <li><Link to="/about">About</Link></li>
    <li><Link to="/topics">Topics</Link></li>
    </ul>

    <hr />

    <Route exact path="/" render={()=><p>Home</p>} />
    <Route path="/about" render={()=><p>about</p>} />
    <Route path="/topics" render={()=><p>topics</p>} />
    </div>
    </Router>
    );

    render(<Example />, document.body);


    Help, how to fix this?










    share|improve this question



























      2












      2








      2


      1






      I used react router v 4.3.1
      When i click on home page link many times, each click creates a new history item. Home page is re-rendered every time. Now your browser navigation is broken (back/forward buttons are not working as expected).



      import React from 'react';
      import { render } from 'react-dom';
      import { BrowserRouter as Router, Route, Link } from 'react-router-dom';

      const Example = () => (
      <Router>
      <div>
      <ul>
      <li><Link to="/">Home</Link></li>
      <li><Link to="/">Home 1</Link></li>
      <li><Link to="/">Home 2</Link></li>
      <li><Link to="/about">About</Link></li>
      <li><Link to="/topics">Topics</Link></li>
      </ul>

      <hr />

      <Route exact path="/" render={()=><p>Home</p>} />
      <Route path="/about" render={()=><p>about</p>} />
      <Route path="/topics" render={()=><p>topics</p>} />
      </div>
      </Router>
      );

      render(<Example />, document.body);


      Help, how to fix this?










      share|improve this question
















      I used react router v 4.3.1
      When i click on home page link many times, each click creates a new history item. Home page is re-rendered every time. Now your browser navigation is broken (back/forward buttons are not working as expected).



      import React from 'react';
      import { render } from 'react-dom';
      import { BrowserRouter as Router, Route, Link } from 'react-router-dom';

      const Example = () => (
      <Router>
      <div>
      <ul>
      <li><Link to="/">Home</Link></li>
      <li><Link to="/">Home 1</Link></li>
      <li><Link to="/">Home 2</Link></li>
      <li><Link to="/about">About</Link></li>
      <li><Link to="/topics">Topics</Link></li>
      </ul>

      <hr />

      <Route exact path="/" render={()=><p>Home</p>} />
      <Route path="/about" render={()=><p>about</p>} />
      <Route path="/topics" render={()=><p>topics</p>} />
      </div>
      </Router>
      );

      render(<Example />, document.body);


      Help, how to fix this?







      javascript reactjs react-router






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited 2 days ago







      Vadim Hulevich

















      asked 2 days ago









      Vadim HulevichVadim Hulevich

      6279




      6279
























          2 Answers
          2






          active

          oldest

          votes


















          1














          It's an old and known issue introduced with React Router v4 and it's currently (AFAIK) unsolved.



          Fortunately it's pretty easy to workaround using a custom history object (something you would do also if you want to keep in sync Redux state with the browser history). True production code should be more robust than what I'm writing here but you can start with this:



          a) First of all use <Router> instead of <BrowserRouter>.



          import { Router, Route, Link } from "react-router-dom";


          b) Creates your own history object (be sure to npm add history if you didn't):



          import createBrowserHistoryfrom "history/createBrowserHistory";

          // ...

          const history = createBrowserHistory();


          c) Replace the push() method with your own implementation:



          const originalHistoryPush = history.push;

          history.push = function(path, state = {}) {
          if (!this.location) {
          originalHistoryPush(path, state);
          return;
          }

          const oldPath = this.location.pathname + this.location.search + this.location.hash;
          if (oldPath !== path || !shallowEqual(state, this.location.state)) {
          originalHistoryPush(path, state);
          } else {
          this.replace(path, state);
          }
          };


          d) Use the custom history:



          <Router history={history}>...</Router>




          Note that I'm using an hypothetical shallowEqual() method for comparison. You can quickly write your own or pick one of the many implementations out there.






          share|improve this answer


























          • your answer good, but it's like "monkey patching", i thinking about this too, but it's not really solution

            – Vadim Hulevich
            2 days ago











          • You're right, it's a workaround until React Router guys decide what to do about this (I didn't check later but if you still have this issue in 4.3.1 then it's probably still unsolved) but there isn't really anything else than a workaround until they fix this directly in <Link> and <NavLink>.

            – Adriano Repetti
            2 days ago













          • what exactly must do "oldHistoryPush" ?

            – Vadim Hulevich
            2 days ago











          • Just typo, it's originalHistoryPush (the default implementation for history.push().)

            – Adriano Repetti
            2 days ago





















          -2














          This should solve your problem, tell me if not.



          import React from 'react';
          import { render } from 'react-dom';
          import { BrowserRouter as Router, Route, Link } from 'react-router-dom';

          const Home = () => <p>Home</p>;
          const About = () => <p>about</p>;
          const Topics = () => <p>topics</p>;

          const Example = () => (
          <Router>
          <div>
          <ul>
          <li><Link to="/">Home</Link></li>
          <li><Link to="/">Home 1</Link></li>
          <li><Link to="/">Home 2</Link></li>
          <li><Link to="/about">About</Link></li>
          <li><Link to="/topics">Topics</Link></li>
          </ul>

          <hr />

          <Route exact path="/" component={Home} />
          <Route path="/about" component={About} />
          <Route path="/topics" component={Topics} />
          </div>
          </Router>
          );

          render(<Example />, document.body);





          share|improve this answer
























          • you just change render to component, it's useless

            – Vadim Hulevich
            2 days ago











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54252787%2flink-component-update-browser-history-when-location-is-the-same%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          2 Answers
          2






          active

          oldest

          votes








          2 Answers
          2






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          1














          It's an old and known issue introduced with React Router v4 and it's currently (AFAIK) unsolved.



          Fortunately it's pretty easy to workaround using a custom history object (something you would do also if you want to keep in sync Redux state with the browser history). True production code should be more robust than what I'm writing here but you can start with this:



          a) First of all use <Router> instead of <BrowserRouter>.



          import { Router, Route, Link } from "react-router-dom";


          b) Creates your own history object (be sure to npm add history if you didn't):



          import createBrowserHistoryfrom "history/createBrowserHistory";

          // ...

          const history = createBrowserHistory();


          c) Replace the push() method with your own implementation:



          const originalHistoryPush = history.push;

          history.push = function(path, state = {}) {
          if (!this.location) {
          originalHistoryPush(path, state);
          return;
          }

          const oldPath = this.location.pathname + this.location.search + this.location.hash;
          if (oldPath !== path || !shallowEqual(state, this.location.state)) {
          originalHistoryPush(path, state);
          } else {
          this.replace(path, state);
          }
          };


          d) Use the custom history:



          <Router history={history}>...</Router>




          Note that I'm using an hypothetical shallowEqual() method for comparison. You can quickly write your own or pick one of the many implementations out there.






          share|improve this answer


























          • your answer good, but it's like "monkey patching", i thinking about this too, but it's not really solution

            – Vadim Hulevich
            2 days ago











          • You're right, it's a workaround until React Router guys decide what to do about this (I didn't check later but if you still have this issue in 4.3.1 then it's probably still unsolved) but there isn't really anything else than a workaround until they fix this directly in <Link> and <NavLink>.

            – Adriano Repetti
            2 days ago













          • what exactly must do "oldHistoryPush" ?

            – Vadim Hulevich
            2 days ago











          • Just typo, it's originalHistoryPush (the default implementation for history.push().)

            – Adriano Repetti
            2 days ago


















          1














          It's an old and known issue introduced with React Router v4 and it's currently (AFAIK) unsolved.



          Fortunately it's pretty easy to workaround using a custom history object (something you would do also if you want to keep in sync Redux state with the browser history). True production code should be more robust than what I'm writing here but you can start with this:



          a) First of all use <Router> instead of <BrowserRouter>.



          import { Router, Route, Link } from "react-router-dom";


          b) Creates your own history object (be sure to npm add history if you didn't):



          import createBrowserHistoryfrom "history/createBrowserHistory";

          // ...

          const history = createBrowserHistory();


          c) Replace the push() method with your own implementation:



          const originalHistoryPush = history.push;

          history.push = function(path, state = {}) {
          if (!this.location) {
          originalHistoryPush(path, state);
          return;
          }

          const oldPath = this.location.pathname + this.location.search + this.location.hash;
          if (oldPath !== path || !shallowEqual(state, this.location.state)) {
          originalHistoryPush(path, state);
          } else {
          this.replace(path, state);
          }
          };


          d) Use the custom history:



          <Router history={history}>...</Router>




          Note that I'm using an hypothetical shallowEqual() method for comparison. You can quickly write your own or pick one of the many implementations out there.






          share|improve this answer


























          • your answer good, but it's like "monkey patching", i thinking about this too, but it's not really solution

            – Vadim Hulevich
            2 days ago











          • You're right, it's a workaround until React Router guys decide what to do about this (I didn't check later but if you still have this issue in 4.3.1 then it's probably still unsolved) but there isn't really anything else than a workaround until they fix this directly in <Link> and <NavLink>.

            – Adriano Repetti
            2 days ago













          • what exactly must do "oldHistoryPush" ?

            – Vadim Hulevich
            2 days ago











          • Just typo, it's originalHistoryPush (the default implementation for history.push().)

            – Adriano Repetti
            2 days ago
















          1












          1








          1







          It's an old and known issue introduced with React Router v4 and it's currently (AFAIK) unsolved.



          Fortunately it's pretty easy to workaround using a custom history object (something you would do also if you want to keep in sync Redux state with the browser history). True production code should be more robust than what I'm writing here but you can start with this:



          a) First of all use <Router> instead of <BrowserRouter>.



          import { Router, Route, Link } from "react-router-dom";


          b) Creates your own history object (be sure to npm add history if you didn't):



          import createBrowserHistoryfrom "history/createBrowserHistory";

          // ...

          const history = createBrowserHistory();


          c) Replace the push() method with your own implementation:



          const originalHistoryPush = history.push;

          history.push = function(path, state = {}) {
          if (!this.location) {
          originalHistoryPush(path, state);
          return;
          }

          const oldPath = this.location.pathname + this.location.search + this.location.hash;
          if (oldPath !== path || !shallowEqual(state, this.location.state)) {
          originalHistoryPush(path, state);
          } else {
          this.replace(path, state);
          }
          };


          d) Use the custom history:



          <Router history={history}>...</Router>




          Note that I'm using an hypothetical shallowEqual() method for comparison. You can quickly write your own or pick one of the many implementations out there.






          share|improve this answer















          It's an old and known issue introduced with React Router v4 and it's currently (AFAIK) unsolved.



          Fortunately it's pretty easy to workaround using a custom history object (something you would do also if you want to keep in sync Redux state with the browser history). True production code should be more robust than what I'm writing here but you can start with this:



          a) First of all use <Router> instead of <BrowserRouter>.



          import { Router, Route, Link } from "react-router-dom";


          b) Creates your own history object (be sure to npm add history if you didn't):



          import createBrowserHistoryfrom "history/createBrowserHistory";

          // ...

          const history = createBrowserHistory();


          c) Replace the push() method with your own implementation:



          const originalHistoryPush = history.push;

          history.push = function(path, state = {}) {
          if (!this.location) {
          originalHistoryPush(path, state);
          return;
          }

          const oldPath = this.location.pathname + this.location.search + this.location.hash;
          if (oldPath !== path || !shallowEqual(state, this.location.state)) {
          originalHistoryPush(path, state);
          } else {
          this.replace(path, state);
          }
          };


          d) Use the custom history:



          <Router history={history}>...</Router>




          Note that I'm using an hypothetical shallowEqual() method for comparison. You can quickly write your own or pick one of the many implementations out there.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited 2 days ago

























          answered 2 days ago









          Adriano RepettiAdriano Repetti

          50.2k14101156




          50.2k14101156













          • your answer good, but it's like "monkey patching", i thinking about this too, but it's not really solution

            – Vadim Hulevich
            2 days ago











          • You're right, it's a workaround until React Router guys decide what to do about this (I didn't check later but if you still have this issue in 4.3.1 then it's probably still unsolved) but there isn't really anything else than a workaround until they fix this directly in <Link> and <NavLink>.

            – Adriano Repetti
            2 days ago













          • what exactly must do "oldHistoryPush" ?

            – Vadim Hulevich
            2 days ago











          • Just typo, it's originalHistoryPush (the default implementation for history.push().)

            – Adriano Repetti
            2 days ago





















          • your answer good, but it's like "monkey patching", i thinking about this too, but it's not really solution

            – Vadim Hulevich
            2 days ago











          • You're right, it's a workaround until React Router guys decide what to do about this (I didn't check later but if you still have this issue in 4.3.1 then it's probably still unsolved) but there isn't really anything else than a workaround until they fix this directly in <Link> and <NavLink>.

            – Adriano Repetti
            2 days ago













          • what exactly must do "oldHistoryPush" ?

            – Vadim Hulevich
            2 days ago











          • Just typo, it's originalHistoryPush (the default implementation for history.push().)

            – Adriano Repetti
            2 days ago



















          your answer good, but it's like "monkey patching", i thinking about this too, but it's not really solution

          – Vadim Hulevich
          2 days ago





          your answer good, but it's like "monkey patching", i thinking about this too, but it's not really solution

          – Vadim Hulevich
          2 days ago













          You're right, it's a workaround until React Router guys decide what to do about this (I didn't check later but if you still have this issue in 4.3.1 then it's probably still unsolved) but there isn't really anything else than a workaround until they fix this directly in <Link> and <NavLink>.

          – Adriano Repetti
          2 days ago







          You're right, it's a workaround until React Router guys decide what to do about this (I didn't check later but if you still have this issue in 4.3.1 then it's probably still unsolved) but there isn't really anything else than a workaround until they fix this directly in <Link> and <NavLink>.

          – Adriano Repetti
          2 days ago















          what exactly must do "oldHistoryPush" ?

          – Vadim Hulevich
          2 days ago





          what exactly must do "oldHistoryPush" ?

          – Vadim Hulevich
          2 days ago













          Just typo, it's originalHistoryPush (the default implementation for history.push().)

          – Adriano Repetti
          2 days ago







          Just typo, it's originalHistoryPush (the default implementation for history.push().)

          – Adriano Repetti
          2 days ago















          -2














          This should solve your problem, tell me if not.



          import React from 'react';
          import { render } from 'react-dom';
          import { BrowserRouter as Router, Route, Link } from 'react-router-dom';

          const Home = () => <p>Home</p>;
          const About = () => <p>about</p>;
          const Topics = () => <p>topics</p>;

          const Example = () => (
          <Router>
          <div>
          <ul>
          <li><Link to="/">Home</Link></li>
          <li><Link to="/">Home 1</Link></li>
          <li><Link to="/">Home 2</Link></li>
          <li><Link to="/about">About</Link></li>
          <li><Link to="/topics">Topics</Link></li>
          </ul>

          <hr />

          <Route exact path="/" component={Home} />
          <Route path="/about" component={About} />
          <Route path="/topics" component={Topics} />
          </div>
          </Router>
          );

          render(<Example />, document.body);





          share|improve this answer
























          • you just change render to component, it's useless

            – Vadim Hulevich
            2 days ago
















          -2














          This should solve your problem, tell me if not.



          import React from 'react';
          import { render } from 'react-dom';
          import { BrowserRouter as Router, Route, Link } from 'react-router-dom';

          const Home = () => <p>Home</p>;
          const About = () => <p>about</p>;
          const Topics = () => <p>topics</p>;

          const Example = () => (
          <Router>
          <div>
          <ul>
          <li><Link to="/">Home</Link></li>
          <li><Link to="/">Home 1</Link></li>
          <li><Link to="/">Home 2</Link></li>
          <li><Link to="/about">About</Link></li>
          <li><Link to="/topics">Topics</Link></li>
          </ul>

          <hr />

          <Route exact path="/" component={Home} />
          <Route path="/about" component={About} />
          <Route path="/topics" component={Topics} />
          </div>
          </Router>
          );

          render(<Example />, document.body);





          share|improve this answer
























          • you just change render to component, it's useless

            – Vadim Hulevich
            2 days ago














          -2












          -2








          -2







          This should solve your problem, tell me if not.



          import React from 'react';
          import { render } from 'react-dom';
          import { BrowserRouter as Router, Route, Link } from 'react-router-dom';

          const Home = () => <p>Home</p>;
          const About = () => <p>about</p>;
          const Topics = () => <p>topics</p>;

          const Example = () => (
          <Router>
          <div>
          <ul>
          <li><Link to="/">Home</Link></li>
          <li><Link to="/">Home 1</Link></li>
          <li><Link to="/">Home 2</Link></li>
          <li><Link to="/about">About</Link></li>
          <li><Link to="/topics">Topics</Link></li>
          </ul>

          <hr />

          <Route exact path="/" component={Home} />
          <Route path="/about" component={About} />
          <Route path="/topics" component={Topics} />
          </div>
          </Router>
          );

          render(<Example />, document.body);





          share|improve this answer













          This should solve your problem, tell me if not.



          import React from 'react';
          import { render } from 'react-dom';
          import { BrowserRouter as Router, Route, Link } from 'react-router-dom';

          const Home = () => <p>Home</p>;
          const About = () => <p>about</p>;
          const Topics = () => <p>topics</p>;

          const Example = () => (
          <Router>
          <div>
          <ul>
          <li><Link to="/">Home</Link></li>
          <li><Link to="/">Home 1</Link></li>
          <li><Link to="/">Home 2</Link></li>
          <li><Link to="/about">About</Link></li>
          <li><Link to="/topics">Topics</Link></li>
          </ul>

          <hr />

          <Route exact path="/" component={Home} />
          <Route path="/about" component={About} />
          <Route path="/topics" component={Topics} />
          </div>
          </Router>
          );

          render(<Example />, document.body);






          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered 2 days ago









          Nikita MalyschkinNikita Malyschkin

          353111




          353111













          • you just change render to component, it's useless

            – Vadim Hulevich
            2 days ago



















          • you just change render to component, it's useless

            – Vadim Hulevich
            2 days ago

















          you just change render to component, it's useless

          – Vadim Hulevich
          2 days ago





          you just change render to component, it's useless

          – Vadim Hulevich
          2 days ago


















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54252787%2flink-component-update-browser-history-when-location-is-the-same%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Liquibase includeAll doesn't find base path

          How to use setInterval in EJS file?

          Petrus Granier-Deferre