You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

useRef+Context API实现滚动跳转:About组件报错失效求助

问题分析与修复方案

错误原因

你当前的代码存在两个核心问题:

  1. 重复渲染Navbar:About和Contact组件内部都各自渲染了Navbar,导致页面会出现多个导航栏,同时每个Navbar仅被当前组件的Context包裹。比如Contact组件中的Navbar只能获取ContactProvider的值,无法访问AboutMeProvider,因此点击About按钮时aboutMeRef为undefined,触发Cannot read properties of undefined (reading 'current')错误。
  2. Context作用域不匹配:每个组件的Context仅覆盖自身内部的Navbar,全局场景下(比如Home页面单独渲染Navbar),两个Context都未提供,会导致所有滚动操作报错。

修复方案:全局Navbar + 父组件统一管理Ref

将Navbar提升为全局组件,在父组件中统一创建滚动所需的Ref,并直接将滚动逻辑传递给Navbar,无需使用Context,逻辑更简洁且避免作用域问题。

1. 父组件(App.js)重构

import React, { useRef } from 'react';
import About from './components/About';
import Contact from './components/Contact';
import Navbar from './components/Navbar';

function App() {
  // 创建两个Ref,分别绑定到About和Contact组件容器
  const aboutMeRef = useRef(null);
  const contactRef = useRef(null);

  // 定义滚动函数,实现平滑滚动
  const scrollToAbout = () => {
    aboutMeRef.current?.scrollIntoView({ behavior: 'smooth', block: 'start' });
  };

  const scrollToContact = () => {
    contactRef.current?.scrollIntoView({ behavior: 'smooth', block: 'start' });
  };

  return (
    <div>
      {/* 全局Navbar,传递滚动回调 */}
      <Navbar onAboutClick={scrollToAbout} onContactClick={scrollToContact} />
      {/* About组件容器绑定Ref */}
      <div ref={aboutMeRef} className="pt-5">
        <About />
      </div>
      {/* Contact组件容器绑定Ref */}
      <div ref={contactRef} className="pt-5">
        <Contact />
      </div>
    </div>
  );
}

export default App;

2. 清理About.js代码

移除内部的Navbar、Context定义及多余Ref:

import React from "react";
import { useWindowScroll } from "react-use";
import second from "../images/second.jpg";
import "bootstrap-icons/font/bootstrap-icons.css";
import instagram from "../images/New folder/png/Instagram.png";
import github from "../images/New folder/png/github.png";
import Linkedin from "../images/New folder/png/Linkedin.png";

export default function About() {
  return (
    <>
      <div className="h1 text-center mt-4 text-name about-heading">About Me</div>
      <hr className="hr hr-blurry" />

      <div className="row about-main mt-4">
        <div className="col aboutCol1 text-center">
          <div className="about-secondCard px-4">
            <img className="about-secondImg" src={second} alt="profile" />
          </div>
        </div>

        <div className="col wannaKnow-main w-75 px-4">
          <div className="h1 text-left mt-4 col2-text row">Wanna Know Me ?</div>
          <hr className="hr hr-blurry" />
          <div className="rowe text-left mt-3 col2-sentence">
            My name is Manglesh Kumar Born in Gorakhpur. I'm doing my graduation of B. Tech Computer Science and Engineering from Kanpur. I am a confident patient and a quick learner.
          </div>
          <a href="/" className="row knowMore btn btn-lg mt-4 active" role="button" aria-pressed="true">Know More</a>
        </div>
      </div>
    </>
  );
}

3. 清理Contact.js代码

移除内部的Navbar、Context定义及多余Ref:

import React from 'react'
import { useWindowScroll } from 'react-use';

export default function Contact() {
  return (
    <>
      <div className="h1 text-left p-2 col2-text row">Get in Touch</div>
      <hr className="hr hr-blurry" />

      <form>
        <div className="mb-3">
          <label htmlFor="exampleInputEmail1" className="form-label">Name</label>
          <input type="text" className="form-control" />
        </div>
        <div className="mb-3">
          <label htmlFor="exampleInputEmail1" className="form-label">E-mail</label>
          <input type="email" className="form-control" />
        </div>
        <div className="mb-3">
          <label htmlFor="exampleInputEmail1" className="form-label">Number</label>
          <input type="text" className="form-control" />
        </div>
        <div className="mb-3">
          <label htmlFor="exampleFormControlTextarea1" className="form-label"> Write Your Message here </label>
          <textarea className="form-control" id="exampleFormControlTextarea1" rows="3"></textarea>
        </div>
        <button type="submit" className="btn btn-primary">Submit</button>
      </form>
    </>
  )
}

4. 重构Navbar.js

接收父组件传递的滚动回调,移除Context相关代码:

import React from 'react'

export default function Navbar({ onAboutClick, onContactClick }) {
  return (
    <>
      <nav className="navbar-css-op navbar navbar-expand-lg bg-light fixed-top">
        <div className="container-fluid">
          <a className="navbar-brand text-dark" href="/">Manglesh</a>
          <button className="navbar-toggler bg-light" type="button" data-bs-toggle="collapse" data-bs-target="#navbarTogglerDemo02" aria-controls="navbarTogglerDemo02" aria-expanded="false" aria-label="Toggle navigation">
            <span className="navbar-toggler-icon"></span>
          </button>

          <div className="collapse navbar-collapse" id="navbarTogglerDemo02">
            <ul className="navbar-nav me-auto mb-2 mb-lg-0">
              <li className="nav-item">
                <a className="nav-link active text-dark" aria-current="page" href="/">Home</a>
              </li>
              <li className="nav-item">
                <div onClick={onAboutClick} className="nav-link active text-dark">About</div>
              </li>
              <li className="nav-item">
                <div onClick={onContactClick} className="nav-link active text-dark">Contacts</div>
              </li>
            </ul>
          </div>
        </div>
      </nav>
    </>
  )
}

优化说明

  1. 平滑滚动:通过scrollIntoView的behavior: 'smooth'参数实现流畅的滚动效果。
  2. 避免内容遮挡:给组件容器添加pt-5类(或自定义padding),防止固定导航栏遮挡组件内容。
  3. 健壮性提升:使用可选链操作符?.,即使组件未挂载也不会触发报错。

内容的提问来源于stack exchange,提问作者nobody

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 15:55:34