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
相关产品推荐
相关产品推荐

