1

(EDITED)
I have a react app where I want to have the navbar on every page. So I made a navbar component and added it to every new page. On the main page, the navbar works fine by scrolling to the selected section. However, on any other page, the navbar cannot scroll to that section because it's not found. So my question is, how do I make the navbar clickable to reroute to the main page THEN scroll to an element.

Here is the simplified code

Navbar Code

export default function navbar(){
    return(
        <div className="nav-container">
        <nav>
            <ul className="desktop-nav">
                    <li>
                        <a
                            className="link-logo" 
                            onClick = {() => {scrollTo('landing-page')}}
                        />
                    </li>
                    <li>
                        <a onClick = {() => {scrollTo('elem1')}}>elem1</a>
                    </li>
                    <li>
                        <a onClick = {() => {scrollTo('elem2')}}>elem2</a>
                    </li>
                    <li>
                        <a onClick = {() => {scrollTo('elem3')}}>elem3</a>
                    </li>
                </ul>
        </nav>
        </div>
    );
}
function scrollTo(elem){
    document.getElementById(elem).scrollIntoView(true);
}

Main page code

export default function Home(){
        return(
            <div>
                <div id = 'elem1'>elem1</div>
                <div id = 'elem2'>elem2</div>
                <div id = 'elem3'>elem3</div>
                <a href = '/somewhere'> Go to Second Page </a>
            </div>
        );
    }

App router


function App() {
  return (
    <Router>
      <Switch>
        <Route exact path = '/' component = {SITE} />
        <Route exact path = '/somewhere' component = {SECOND_PAGE}/>
      </Switch>
    </Router>
  );
}

export default App;

Now from SECOND_PAGE component which is displayed as a separate page, how can I make the navbar links go to SITE component and scroll to the specified link without adding anything to the URL. I don't want the users to be able to see my div IDs and classnames if possible. I want the URL to be static as I navigate through those two components.

PlagueDr
  • 25
  • 4
  • 2
    You may want to first implement routing/navigation into your project via [react-router-dom](https://reactrouter.com/web/guides/quick-start), and then to link to specific anchor tags on a page, add [react-router-hash-link](https://www.npmjs.com/package/react-router-hash-link). – Drew Reese Sep 12 '21 at 01:17
  • I have already set up react-router-dom to take me to different pages. react-router-hash-link doesn't seem to be fixing the issue I am having. I want to have the nav links go to the home page and scroll to the specified section without adding anything to the URL. – PlagueDr Sep 14 '21 at 21:01
  • Well, what you describe you want (other than displaying the anchor target in the URL) is exactly what hash-links do. Is there an issue with letting users see where they will navigate to? I suppose you could use route state and specify a scroll target. Can you update your question to include the relevant routing/navigation code so that we can see how you are rendering the routes and attempting to link into the home page? – Drew Reese Sep 14 '21 at 21:31
  • 1
    You can pass navbar component outside of switch so that it shows on every page. I would suggest using Link tag of react-router-dom instead of a tag. – Ranveer Sequeira Sep 15 '21 at 05:10
  • This topic maybe will can help you https://stackoverflow.com/questions/33188994/scroll-to-the-top-of-the-page-after-render-in-react-js – Waker Sep 26 '21 at 06:30

1 Answers1

0

I suggest adding react-router-hash-link to your project to allow linking/navigating to a page, and scrolling into view a specific section by id attribute.

Example using your code:

import { Link, Switch, Route } from "react-router-dom";
import { HashLink } from "react-router-hash-link";

const NavBar = () => (
  <div className="nav-container">
    <nav>
      <ul className="desktop-nav">
        <li>
          <HashLink smooth to="/#">
            Home
          </HashLink>
        </li>
        <li>
          <HashLink smooth to="/#elem1">
            elem1
          </HashLink>
        </li>
        <li>
          <HashLink smooth to="/#elem2">
            elem2
          </HashLink>
        </li>
        <li>
          <HashLink smooth to="/#elem3">
            elem3
          </HashLink>
        </li>
      </ul>
    </nav>
  </div>
);

const Home = () => {
  return (
    <div>
      <div className="section" id="elem1">
        elem1
      </div>
      <div className="section" id="elem2">
        elem2
      </div>
      <div className="section" id="elem3">
        elem3
      </div>
      <Link to="/somewhere"> Go to Second Page </Link>
    </div>
  );
};

const SecondPage = () => <h1>Second Page</h1>;

export default function App() {
  return (
    <div className="App">
      <NavBar />
      <Switch>
        <Route path="/somewhere" component={SecondPage} />
        <Route path="/" component={Home} />
      </Switch>
    </div>
  );
}

Edit how-to-use-a-navbar-in-react-app-to-reroute-to-a-page-then-scroll-to-an-element

Drew Reese
  • 165,259
  • 14
  • 153
  • 181