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

如何在元素获得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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 15:39:02