Прокрутите вверх, если изменение маршрута не работает

Я работаю над проектом React, где мне нужно, чтобы страница прокручивалась вверх при переходе на новый маршрут. Я реализовал компонент ScrollToTop, но он, похоже, не работает. Страница сохраняет положение прокрутки после навигации.

Несмотря на реализацию компонента ScrollToTop и проверку того, что console log выводит правильные имена путей, страница не прокручивается вверх при изменении маршрута. Предыдущее положение прокрутки сохраняется.

Действия по устранению неполадок

  • Проверено, что оператор console.info в ScrollToTop.js работает и записывает правильные пути.
  • Гарантировано, что ScrollToTop включен в App.js и обертывает Routes.

Дополнительная информация

Код можно найти в моем репозитории GitHub

Я реализовал компонент ScrollToTop, который использует хук useEffect для прокрутки вверх страницы при изменении пути. Я ожидал, что этот компонент будет сбрасывать позицию прокрутки в верхнюю часть страницы при каждом изменении маршрута.

Однако, несмотря на правильное размещение компонента и регистрацию изменений имени пути, страница по-прежнему сохраняет предыдущую позицию прокрутки после навигации, что не является предполагаемым поведением.

Я также хочу сказать, что я прочитал все соответствующие сообщения по этому вопросу в Stack Overflow, и, похоже, мне ничего не помогло. Я перепробовал все ресурсы, чтобы попытаться решить эту проблему.

Ответы на другие вопросы не работают в моем сценарии.

Приложение.js:

import React, { useState, useRef } from "react";
import { BrowserRouter as Router, Route, Routes } from "react-router-dom";
import NavBar from "./components/NavBar.js";
import Contact from "./components/Contact.js";
import Widgets from "./components/widgets/Widgets.js";
import Footer from "./components/Footer.js";
import Currency from "./components/widgets/Currency.js";
import Timer from "./components/widgets/Timer.js";
import Weather from "./components/widgets/Weather.js";
import MainPage from "./components/MainPage.js";
import ScrollToTop from "./components/ScrollToTop.js";

function App() {
  const [isSidebarVisible, setIsSidebarVisible] = useState(true);

  const toggleSidebar = () => setIsSidebarVisible(!isSidebarVisible);

  const personalRef = useRef(null);
  const skillsRef = useRef(null);
  const workRef = useRef(null);
  const educationRef = useRef(null);
  const publicationsRef = useRef(null);

  const refs = {
    personal: personalRef,
    skills: skillsRef,
    work: workRef,
    education: educationRef,
    publications: publicationsRef,
  };

  return (
    <Router>
      <ScrollToTop />
      <div className = "flex min-h-screen overflow-hidden">
        <NavBar 
          isSidebarVisible = {isSidebarVisible} 
          toggleSidebar = {toggleSidebar} 
          refs = {refs}
        />
        <div
          className = {`flex-1 flex flex-col transition-all duration-300 ${
            isSidebarVisible ? "ml-20" : "ml-0"
          }`}
        >
          <header className = "flex justify-between items-center p-8 bg-gray-800 text-white fixed w-full top-0 left-0 z-30 transition-all duration-300">
            <h1
              className = {`text-2xl transition-all duration-300 ${
                isSidebarVisible ? "ml-20" : "ml-0"
              }`}
            >
              Richard Lechko - IT Student @ DePaul University
            </h1>
            <button
              onClick = {toggleSidebar}
              className = "p-2 bg-blue-500 text-white rounded"
            >
              {isSidebarVisible ? "Close Sidebar" : "Open Sidebar"}
            </button>
          </header>
          <main className = "flex-1 flex flex-col pt-24 overflow-hidden">
            <Routes>
              <Route
                path = "/"
                element = {
                  <MainPage
                    personalRef = {personalRef}
                    skillsRef = {skillsRef}
                    workRef = {workRef}
                    educationRef = {educationRef}
                    publicationsRef = {publicationsRef}
                  />
                }
              />
              <Route path = "/contact" element = {<Contact />} />
              <Route path = "/widgets" element = {<Widgets />} />
              <Route path = "/widgets/currency" element = {<Currency />} />
              <Route path = "/widgets/timer" element = {<Timer />} />
              <Route path = "/widgets/weather" element = {<Weather />} />
            </Routes>
            <Footer refs = {refs} />
          </main>
        </div>
      </div>
    </Router>
  );
}

export default App;

ПрокруткаToTop.js:

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

const ScrollToTop = () => {
  const { pathname } = useLocation();

  useEffect(() => {
    console.info('ScrollToTop: Pathname changed to', pathname);
    setTimeout(() => {
      window.scrollTo(0, 0);
    }, 0);
  }, [pathname]);

  return null;
};

export default ScrollToTop;

NavBar.js:

import React, { useEffect } from "react";
import { useNavigate, useLocation } from "react-router-dom";
import {
  FaUser,
  FaTools,
  FaBriefcase,
  FaGraduationCap,
  FaBook,
  FaEnvelope,
} from "react-icons/fa";

const NavBar = ({ isSidebarVisible, refs, toggleSidebar }) => {
  const navigate = useNavigate();
  const location = useLocation();

  const handleNavClick = (sectionId) => {
    if (refs[sectionId] && refs[sectionId].current) {
      refs[sectionId].current.scrollIntoView({ behavior: "smooth" });
    } else {
      navigate("/");
      setTimeout(() => {
        if (refs[sectionId] && refs[sectionId].current) {
          refs[sectionId].current.scrollIntoView({ behavior: "smooth" });
        }
      }, 100);
    }
  };

  const handleExternalNavClick = (path) => {
    navigate(path, { replace: true });
  };

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

  return (
    <div
      className = {`fixed top-0 h-screen ${
        isSidebarVisible ? "w-20" : "w-0"
      } bg-gray-900 text-white shadow-lg transition-all duration-300 z-40`}
    >
      <nav>
        <ul>
          <NavItem icon = {<FaUser size = {28} />} onClick = {() => handleNavClick('personal')} />
          <NavItem icon = {<FaTools size = {28} />} onClick = {() => handleNavClick('skills')} />
          <NavItem icon = {<FaBriefcase size = {28} />} onClick = {() => handleNavClick('work')} />
          <NavItem icon = {<FaGraduationCap size = {28} />} onClick = {() => handleNavClick('education')} />
          <NavItem icon = {<FaBook size = {28} />} onClick = {() => handleNavClick('publications')} />
          <NavItem icon = {<FaEnvelope size = {28} />} onClick = {() => handleExternalNavClick('/contact')} />
          <NavItem icon = {<FaTools size = {28} />} onClick = {() => handleExternalNavClick('/widgets')} />
        </ul>
      </nav>
    </div>
  );
};

const NavItem = ({ icon, onClick }) => {
  return (
    <li onClick = {onClick}>
      <div className = "flex justify-center items-center p-4 hover:bg-gray-700 transition-colors cursor-pointer">
        {icon}
      </div>
    </li>
  );
};

export default NavBar;
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
0
56
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

window.scrollTo(0,0) недействителен, потому что само окно вашего окна не может прокручиваться, попробуйте window.document.body.scrollTo(0,0)

Спасибо, это очень помогло!

Richard Lechko 11.08.2024 07:02

Другие вопросы по теме