Marty
Marty

Reputation: 153

React scroll to top when opening a new page not working

I need react to open new pages from the top.

My goToTop.js:

    import { useEffect } from "react";
import { useLocation } from "react-router-dom";

export default function ScrollToTop() {
  const { pathname } = useLocation();

  useEffect(() => {
    window.scrollTo(0, 0);
  }, [pathname]);

  return null;
}

Sometimes it does scroll to the top and sometimes it doesn't. It seems as if the element that the user clicked on is lower than the size of the next page it won't work. I'm confused on why this does not work.

I've tried this in the componentOnMount and componentOnUpdate:

var something = document.getElementById('someid')
something.scrollIntoView()

But this does not work either. It can not find the element in unmount and it does not work in update

My app.js looks like this:

return (
    <StrictMode>
      <BrowserRouter>
      <ScrollToTop />
        <header className='navMenu'>
          <div className='navMenuInside'>
            <div className='navMenuCenter'>
              <Link onClick={handleLinkClick}>About</Link>
              <Link className="activeMenu" to="/">Projects</Link>
              <Link onClick={sendEmail}>E-mail</Link>
            </div>
          </div>
        </header>
        <Routes>
          <Route path="/projects/:id" element={<Details />} />
          <Route path="/" element={<Projects />} />
        </Routes>
        <Footer 
                linkedin={info.linkedin} 
                />
      </BrowserRouter>
    </StrictMode>
  );

Upvotes: 0

Views: 3311

Answers (2)

Shiplu
Shiplu

Reputation: 516

You don't need to deal with children from the Cyrus Zei's answer. Simply create a component and use it before App component.

In Component:

export const ScrollToTop = () => {
  const location = useLocation();

  useEffect(() => {
    window.scrollTo(0, 0);
  }, [location]);

  return null;
}

No use it before App component:

  <React.StrictMode>
    <Router>
      <ScrollToTop/>
      <App/>
    </Router>
  </React.StrictMode>

Upvotes: 0

Cyrus Zei
Cyrus Zei

Reputation: 2660

You should try to make an Wrapped component

something like this :

const Wrapper = ({ children }) => {
  const location = useLocation();
  useLayoutEffect(() => {
    document.documentElement.scrollTo(0, 0);
  }, [location.pathname]);
  return children;
};

then wrapp it around your App or component

<Wrapper>
    <App/>
</Wrapper>

Upvotes: 2

Related Questions