React中如何检测父组件内的子input元素是否获取焦点?
当然有办法啦!这里给你两种实用的方案,结合你的代码场景来详细说明:
方案一:通过Ref转发直接获取DOM节点判断焦点
这个方法适合需要直接操作input DOM元素的场景,核心是把父组件的ref转发到子input上,再通过DOM API判断焦点状态。
首先修改你的Component组件,用forwardRef实现ref转发:
import { forwardRef, useRef, useState, useEffect } from 'react'; // 用forwardRef包装组件,接收ref参数 const Component = forwardRef((props, ref) => { return ( <div className="nice"> {/* 把父组件传入的ref绑定到子input上 */} {React.cloneElement(props.children, { ref })} </div> ); }); // 父组件中使用 const Parent = () => { const inputRef = useRef(null); const [isInputFocused, setIsInputFocused] = useState(false); useEffect(() => { const inputElement = inputRef.current; if (!inputElement) return; // 给input绑定焦点事件 const handleFocus = () => setIsInputFocused(true); const handleBlur = () => setIsInputFocused(false); inputElement.addEventListener('focus', handleFocus); inputElement.addEventListener('blur', handleBlur); // 组件卸载时清除监听 return () => { inputElement.removeEventListener('focus', handleFocus); inputElement.removeEventListener('blur', handleBlur); }; }, []); return ( <div> <Component ref={inputRef}> <input placeholder="试试点击我" /> </Component> <p>当前input状态:{isInputFocused ? '*已聚焦*' : '未聚焦'}</p> </div> ); };
方案二:通过事件回调传递焦点状态
如果不想直接操作DOM,这种“React式”的状态传递更优雅——让input把焦点变化通过回调告知父组件:
import { useState } from 'react'; const Component = (props) => { return ( <div className="nice"> {/* 给子input添加focus/blur事件,把状态通过props传递出去 */} {React.cloneElement(props.children, { onFocus: () => props.onFocusChange(true), onBlur: () => props.onFocusChange(false), })} </div> ); }; // 父组件中使用 const Parent = () => { const [isInputFocused, setIsInputFocused] = useState(false); return ( <div> <Component onFocusChange={setIsInputFocused}> <input placeholder="点击看看状态变化" /> </Component> <p>当前input状态:{isInputFocused ? '*已聚焦*' : '未聚焦'}</p> </div> ); };
小提示
- 如果你的
props.children包含多个元素,需要遍历找到目标input再绑定ref或事件,上面的示例默认只有一个input子元素。 - 方案一中也可以用
document.activeElement === inputRef.current来判断焦点,适合需要实时检查的场景,但绑定元素自身的focus/blur事件性能更优。
内容的提问来源于stack exchange,提问作者handsome
相关产品推荐
相关产品推荐

