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

React中如何使用useRef访问DOM元素实现点击按钮隐藏导航列表

实现步骤

整个实现的核心逻辑是:在父组件Navigation中创建ref实例,通过props分别传递给对应的子组件:将ref绑定到NavigationList的根DOM元素上,将点击处理函数传递给NavigationBtn绑定到按钮点击事件。

1. 父组件Navigation实现

首先在父组件中用useRef创建ref,编写点击处理函数,将ref和处理函数分别传递给子组件:

import { useRef } from 'react';
import NavigationHeader from './NavigationHeader';
import NavigationList from './NavigationList';
import NavigationBtn from './NavigationBtn';

function Navigation() {
  // 创建ref用于存储NavigationList的DOM节点引用
  const navigationListRef = useRef(null);

  const btnClickHandler = () => {
    // 先判断ref是否指向了已挂载的节点,避免报错
    if (navigationListRef.current) {
      // 注意:display属性隐藏元素取值为none,hidden是visibility属性的取值
      navigationListRef.current.style.display = 'none';
      // 如果需要保留元素占位空间,改用visibility属性
      // navigationListRef.current.style.visibility = 'hidden';
    }
  };

  return (
    <div className="navigation-wrapper">
      <NavigationHeader />
      {/* 把ref传递给NavigationList组件 */}
      <NavigationList ref={navigationListRef} />
      {/* 把点击处理函数传递给NavigationBtn组件 */}
      <NavigationBtn onClick={btnClickHandler} />
    </div>
  );
}

export default Navigation;

2. NavigationList组件实现

函数组件默认无法直接接收ref属性,需要用forwardRef包裹,才能把父组件传递的ref绑定到内部DOM上:

import { forwardRef } from 'react';

// forwardRef的第二个参数就是父组件传递过来的ref
const NavigationList = forwardRef((props, ref) => {
  return (
    <ul ref={ref} className="navigation-list">
      <li>菜单项1</li>
      <li>菜单项2</li>
      <li>菜单项3</li>
      {/* 其他列表内容 */}
    </ul>
  );
});

export default NavigationList;

3. NavigationBtn组件实现

直接接收父组件传递的onClick方法,绑定到按钮的点击事件即可:

function NavigationBtn({ onClick }) {
  return (
    <button onClick={onClick} className="toggle-btn">
      隐藏菜单
    </button>
  );
}

export default NavigationBtn;
补充说明

如果只是单纯控制元素的显示隐藏,更符合React声明式编程思路的方案是用state控制,不需要操作DOM也不需要使用ref,优先推荐这种写法:

import { useState } from 'react';
import NavigationHeader from './NavigationHeader';
import NavigationList from './NavigationList';
import NavigationBtn from './NavigationBtn';

function Navigation() {
  // 用state控制列表是否显示
  const [isListShow, setIsListShow] = useState(true);

  const btnClickHandler = () => {
    setIsListShow(false);
  };

  return (
    <div className="navigation-wrapper">
      <NavigationHeader />
      <NavigationList style={{ display: isListShow ? 'block' : 'none' }} />
      <NavigationBtn onClick={btnClickHandler} />
    </div>
  );
}

export default Navigation;

只有在必须直接操作DOM的场景(比如控制滚动位置、触发DOM原生动画、调用DOM原生API等)下,再优先选择ref方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 17:57:03