如何在TreeView的子节点中检测按键按下事件?
问题:TreeView与TreeItem的onKeyDown事件无响应
我使用Material-UI的TreeView组件,结构如下:
<TreeView sx={style} id="xxx" aria-label="files" defaultCollapseIcon={<ExpandMoreIcon />} defaultExpandIcon={<ChevronRightIcon />} expanded={expanded} onNodeToggle={handleToggle} onNodeSelect={handleSelect} onKeyDown={e => console.log('key press!!')} > {output} </TreeView>
其中output是JSX.Element[]类型的数组,生成代码如下:
const output:JSX.Element[] = []; args.nodeid++; for(const msg of item.msgs) { const idstr = args.nodeid.toString(); output.push( <TreeItem key={idstr} nodeId={idstr} label={msg.content} icon={getIco(msg.kind)} /> ) args.nodeid++; }
但无论点击哪个子节点后按键,TreeView的onKeyDown都没触发。给TreeItem单独加onKeyDown也没用:
output.push( <TreeItem key={idstr} nodeId={idstr} label={msg.content} icon={getIco(msg.kind)} onKeyDown={e => console.log('key press from child!!')} /> )
请问该怎么修复?
解决方法
给TreeItem添加可聚焦属性:TreeItem默认可能无法获取焦点,导致键盘事件无法触发。给每个TreeItem加上
tabIndex={0},让它能够被聚焦,这样按键事件就能被捕获:<TreeItem key={idstr} nodeId={idstr} label={msg.content} icon={getIco(msg.kind)} tabIndex={0} onKeyDown={e => console.log('key press from child!!')} />确保TreeView或节点处于焦点状态:键盘事件只有在元素获得焦点时才会触发。可以点击TreeItem让它聚焦,或者通过ref给TreeView初始化聚焦:
import { useRef, useEffect } from 'react'; const treeRef = useRef(null); useEffect(() => { treeRef.current?.focus(); }, []); <TreeView ref={treeRef} // 其他属性不变 onKeyDown={e => console.log('key press!!', e.key)} > {output} </TreeView>检查label组件是否阻止事件冒泡:如果你的
label是自定义组件,要确保它没有调用e.stopPropagation()或e.preventDefault(),否则事件无法传递到TreeItem或TreeView。如果需要保留label的交互,可以给label加tabIndex={-1},让焦点落到TreeItem上。验证受控状态逻辑:如果
expanded是受控状态,确认handleToggle正确更新了状态值,异常的节点展开状态可能会干扰事件系统的正常工作。
内容的提问来源于stack exchange,提问作者Jack
相关产品推荐
相关产品推荐

