如何在元素获得focus时显示按钮?有没有更优雅的React实现方案?
优化实现方案
你的原有实现可以从几个维度优化,更简洁高效:
- 去掉全局document的focus事件绑定,避免全局事件污染和多实例冲突
- 直接使用支持冒泡的
focusin/focusout事件绑定到容器,不需要额外判断document.activeElement - 状态完全内聚,如果你需要多行列的场景,直接封装成独立组件复用即可
优化后代码示例
import { useState } from 'react'; // 可复用的行组件,每行包含两个input+对应的操作按钮 const InputRow = () => { const [showSave, setShowSave] = useState(false); const [input1, setInput1] = useState(''); const [input2, setInput2] = useState(''); const handleSave = () => { console.log('保存内容:', input1, input2); // 保存完成后可以主动失焦隐藏按钮 setShowSave(false); }; return ( // 直接在容器上绑focusin/focusout事件 <div onFocusin={() => setShowSave(true)} onFocusout={(e) => { // 判断失焦后焦点是否还在当前容器内,避免点击按钮时触发隐藏 if (!e.currentTarget.contains(e.relatedTarget)) { setShowSave(false); } }} style={{ margin: '10px 0' }} > <input type="text" value={input1} onChange={(e) => setInput1(e.target.value)} style={{ marginRight: '8px' }} /> <input type="text" value={input2} onChange={(e) => setInput2(e.target.value)} style={{ marginRight: '8px' }} /> <button type="button" onClick={handleSave} style={{ visibility: showSave ? 'visible' : 'hidden', marginRight: '8px' }} > 保存 </button> </div> ) } // 父组件直接复用行组件即可 export default () => { return ( <div> <InputRow /> <InputRow /> <InputRow /> {/* 需要多少行就加多少个InputRow */} </div> ) }
最高性能可选方案(纯CSS实现)
完全不需要JS控制状态,用:focus-within伪类即可实现,性能最优:
/* 给行容器加row类名,保存按钮加save-btn类名 */ .row:not(:focus-within) .save-btn { visibility: hidden; }
内容的提问来源于stack exchange,提问作者user3808059
相关产品推荐
相关产品推荐

