使用react-anchor-link-smooth-scroll点击导航栏无法滚动到对应区块求助
解决react-anchor-link-smooth-scroll点击无滚动反应的问题
你的问题核心在于滚动容器指定错误:App组件最外层div设置了overflow-y-scroll,页面的滚动实际发生在这个容器内,而非window,但react-anchor-link-smooth-scroll默认监听window滚动,导致无法触发正确的滚动行为。
修复步骤:
给滚动容器添加Ref并传递给Navbar
修改App组件,引入useRef绑定到滚动容器,再将Ref传递给Navbar:import {React, useEffect, useState, useRef} from "react"; import Hero from "./Hero"; import About from "./About"; import Navbar from "./Navbar"; import WorkExperience from "./WorkExperience"; import Contact from "./Contact"; function App() { const [selectedPage, setSelectedPage] = useState("home"); const [isTopOfPage, setIsTopOfPage] = useState(true); const scrollContainerRef = useRef(null); useEffect(() => { const handleScroll = () => { if (window.scrollY === 0) { setIsTopOfPage(true); setSelectedPage("home"); } if (window.scrollY !== 0) setIsTopOfPage(false); }; window.addEventListener("scroll", handleScroll); return () => window.removeEventListener("scroll", handleScroll); }, []); return ( <div ref={scrollContainerRef} className="bg-[rgb(36,36,36)] text-white h-screen snap-y snap-mandatory overflow-y-scroll overflow-x-hidden z-0 scrollbar scrollbar-track-gray-400/20 scrollbar-thumb-[#0A81F7]/80" > <Navbar isTopOfPage={isTopOfPage} selectedPage={selectedPage} setSelectedPage={setSelectedPage} scrollContainerRef={scrollContainerRef} /> <section id="home"> <Hero/> </section> <section id="about"> <About/> </section> <section id="experience"> <WorkExperience/> </section> </div> ); } export default App;在AnchorLink中指定滚动容器
修改Navbar组件,接收scrollContainerRef并传递给AnchorLink的scrollElement属性:import React, { useState } from "react"; import { SocialIcon } from "react-social-icons"; import { motion } from "framer-motion"; import AnchorLink from "react-anchor-link-smooth-scroll"; import { Menu as MenuIcon, Clear as ClearIcon } from '@mui/icons-material'; import useMediaQuery from "./hooks/useMediaQuery"; const Link = ({ page, selectedPage, setSelectedPage, scrollContainerRef }) => { const lowerCasePage = page.toLowerCase(); return ( <AnchorLink style={{ padding: "0.5rem 1rem", border: "1px solid #242424", borderRadius: "9999px", textTransform: "uppercase", fontSize: "0.75rem", letterSpacing: "0.125rem", color: selectedPage === lowerCasePage ? "#0A81F7" : "#FF8C00", transition: "all 0.3s", ":hover": { borderColor: "#FF8C00", color: "#0A81F7", }, }} href={`#${lowerCasePage}`} scrollElement={scrollContainerRef.current} onClick={() => setSelectedPage(lowerCasePage)} > {page} </AnchorLink> ); }; const Navbar = ({ selectedPage, setSelectedPage, scrollContainerRef }) => { const [isMenuToggled, setIsMenuToggled] = useState(false); const isDesktop = useMediaQuery("(min-width: 768px)"); return ( <nav className="sticky top-0 p-5 flex items-start justify-between max-w-8xl mx-auto z-20 xl:items-center"> <motion.div initial={{ x: -500, opacity: 0, scale: 0.5, }} animate={{ x: 0, opacity: 1, scale: 1, }} transition={{ duration: 1.5, }} className="flex flex-row items-center" > <SocialIcon url="https://www.linkedin.com/in/jeremy-carpenter-1119b393/" fgColor="gray" bgColor="transparent" /> <SocialIcon url="https://github.com/buckoon" fgColor="gray" bgColor="transparent" /> </motion.div> {isDesktop ? ( <motion.div initial={{ x: 500, opacity: 0, scale: 0.5, }} animate={{ x: 0, opacity: 1, scale: 1, }} transition={{ duration: 1.5 }} className="flex flex-row items-center text-gray-300 cursor-pointer" > <div className="pt-7 ml-5"> <Link page="Home" selectedPage={selectedPage} setSelectedPage={setSelectedPage} scrollContainerRef={scrollContainerRef} /> <Link page="About" selectedPage={selectedPage} setSelectedPage={setSelectedPage} scrollContainerRef={scrollContainerRef} /> <Link page="Experience" selectedPage={selectedPage} setSelectedPage={setSelectedPage} scrollContainerRef={scrollContainerRef} /> <Link page="Skills" selectedPage={selectedPage} setSelectedPage={setSelectedPage} scrollContainerRef={scrollContainerRef} /> <Link page="Projects" selectedPage={selectedPage} setSelectedPage={setSelectedPage} scrollContainerRef={scrollContainerRef} /> <Link page="Contact" selectedPage={selectedPage} setSelectedPage={setSelectedPage} scrollContainerRef={scrollContainerRef} /> </div> </motion.div> ) : ( <button className="rounded-full bg-red p-2" onClick={() => setIsMenuToggled(!isMenuToggled)} > <MenuIcon /> </button> )} {!isDesktop && isMenuToggled && ( <div className="fixed right-0 bottom-0 h-full bg-blue w-[300px]"> <div className="flex justify-end p-12"> <button onClick={() => setIsMenuToggled(!isMenuToggled)}> <ClearIcon/> </button> </div> <div className="flex flex-col gap-10 ml-[33%] text-2xl text-deep-blue"> <Link page="Home" selectedPage={selectedPage} setSelectedPage={setSelectedPage} scrollContainerRef={scrollContainerRef} /> <Link page="About" selectedPage={selectedPage} setSelectedPage={setSelectedPage} scrollContainerRef={scrollContainerRef} /> <Link page="Experience" selectedPage={selectedPage} setSelectedPage={setSelectedPage} scrollContainerRef={scrollContainerRef} /> <Link page="Skills" selectedPage={selectedPage} setSelectedPage={setSelectedPage} scrollContainerRef={scrollContainerRef} /> <Link page="Projects" selectedPage={selectedPage} setSelectedPage={setSelectedPage} scrollContainerRef={scrollContainerRef} /> <Link page="Contact" selectedPage={selectedPage} setSelectedPage={setSelectedPage} scrollContainerRef={scrollContainerRef} /> </div> </div> )} </nav> ); } export default Navbar;
额外检查点:
- 确认所有板块的
id与AnchorLink的href一一对应(你的代码中这部分逻辑正确) - 确保
react-anchor-link-smooth-scroll为最新版本,避免版本兼容问题
内容的提问来源于stack exchange,提问作者Chickenwhisperer
相关产品推荐
相关产品推荐

