React中BottomSheet显示时如何聚焦内部Input元素?
解决方案
导致focus无效的核心原因通常是调用focus时Input还未完成DOM挂载,或者BottomSheet的动画尚未结束,可以尝试以下几种解决方式:
1. 利用BottomSheet的显示完成回调(推荐)
绝大多数成熟的BottomSheet组件都会提供「显示完成」的回调(比如onOpen、onShown、onTransitionEnd),在这个回调里触发focus,能确保Input已经完全就绪:
const bottomSheetPage = (props) => { const [bottomSheetOn, setBottomSheetOn] = useState(false) const inputRef = useRef<HTMLInputElement>(null) // 假设你的BottomSheet组件有onShown回调 const handleBottomSheetShown = () => { if (props.autoFocus) { inputRef.current?.focus() } } return ( <BottomSheet isOpen={bottomSheetOn} onShown={handleBottomSheetShown} > <input ref={inputRef} /> </BottomSheet> ) }
2. 延迟调用focus
如果没有现成的回调,可以通过setTimeout给DOM更新和动画留足时间:
useEffect(() => { if (bottomSheetOn && props.autoFocus) { const timer = setTimeout(() => { inputRef.current?.focus() }, 100) // 时间可根据BottomSheet动画时长调整 return () => clearTimeout(timer) // 清理定时器防止内存泄漏 } }, [bottomSheetOn, props.autoFocus])
3. 改用useLayoutEffect同步执行
useLayoutEffect会在DOM更新完成后立即同步执行,比useEffect更早触发,适合需要紧跟DOM变更的场景:
import { useLayoutEffect } from 'react' // ... useLayoutEffect(() => { if (bottomSheetOn && props.autoFocus) { inputRef.current?.focus() } }, [bottomSheetOn, props.autoFocus])
4. 确认Input的渲染逻辑
检查BottomSheet的显示逻辑:
- 确保Input是条件渲染(如
{bottomSheetOn && <input ref={inputRef} />}),而非通过display: none或visibility: hidden隐藏 - 若使用样式隐藏,需确保显示时Input的
display属性不为none(display: none的元素无法获取焦点)
内容的提问来源于stack exchange,提问作者Mike
相关产品推荐
相关产品推荐

