React中使用useRef实现元素blur遇阻?多元素及事件冲突问题
问题分析与解决方案
你的代码里有两个关键问题导致blur操作失效:
1. 单个useRef无法绑定多个元素
你给所有<a>标签都用了同一个inboxItem ref,React会把最后一个挂载的元素赋值给这个ref的current属性,前面的元素都会被覆盖,所以你根本无法拿到所有需要操作的元素。
2. blur方法的调用方式错误
即使ref绑定正确,你写的inboxItem.blur只是引用了这个方法,没有执行它;而且useRef的DOM元素存在于current属性里,正确的调用应该是inboxItem.current?.blur()(用可选链避免null报错)。
方案一:用ref数组管理所有元素
如果需要精准控制每个元素,可以用一个ref数组来存储所有inbox-item的DOM节点:
import { useRef } from 'react'; function Inbox() { // 初始化一个空数组的ref const inboxItemsRef = useRef([]); const toggleDrawer = (id) => () => { alert(id); // 遍历所有ref,对每个元素执行blur inboxItemsRef.current.forEach(item => { item?.blur(); }); }; return ( <> <a className="inbox-item" onClick={toggleDrawer(1)} ref={el => inboxItemsRef.current[0] = el} > <h4>item 1</h4> </a> <a className="inbox-item" onClick={toggleDrawer(2)} ref={el => inboxItemsRef.current[1] = el} > <h4>item 2</h4> </a> </> ); } export default Inbox;
方案二:直接通过选择器批量操作(更简洁)
如果不需要单独控制每个元素,直接用DOM选择器获取所有.inbox-item元素并执行blur,这种方式更简单:
import { useRef } from 'react'; function Inbox() { const toggleDrawer = (id) => () => { alert(id); // 获取所有inbox-item元素,逐个执行blur document.querySelectorAll('.inbox-item').forEach(item => { item?.blur(); }); }; return ( <> <a className="inbox-item" onClick={toggleDrawer(1)}> <h4>item 1</h4> </a> <a className="inbox-item" onClick={toggleDrawer(2)}> <h4>item 2</h4> </a> </> ); } export default Inbox;
另外,注意你的JSX返回了多个相邻元素,需要用<>或<div>包裹,否则会报错(我在示例里已经补上了)。
内容的提问来源于stack exchange,提问作者Zak
相关产品推荐
相关产品推荐

