我试图在安装元素时将焦点添加到输入字段上。我使用这个代码。当我按下标题上的按钮时,搜索栏就会出现,我会将类添加到其中打开,因为
希望我的搜索在转换的帮助下移动。搜索栏开始移动并到达其位置焦点被应用。很好。然后我点击";关闭";按钮来隐藏搜索栏并使其平滑回到它的位置(向后,隐藏起来(。到现在为止一切都好。因为在那之后,搜索栏就会出现即使我按下了关闭按钮,它也不会隐藏!我希望
onClick={() => { props.setVisibleSearchBar(false) }}
将隐藏我的搜索。顺便说一下;打开";也没有当搜索在关闭btn之后意外出现时应用单击(尽管搜索可见(。
页眉.jsx
const Header = () => {
const [visibleSearchBar, setVisibleSearchBar] = useState(false);
return (
<button onClick={() => setVisibleSearchBar(true)}>Show search bar</button>
<Search visibleSearchBar={visibleSearchBar}
setVisibleSearchBar={setVisibleSearchBar} />
);
}
Search.jsx
const Header = (props) => {
const [disabled, setDisabled] = useState(true);
let slideRef = useRef('');
let inputRef = useRef('');
useEffect(() => {
const callback = () => {
setDisabled(false);
inputRef.current.focus();
}
slideRef.current.addEventListener('transitionend', callback);
return () => slideRef.current.removeEventListener('transitionend', callback)
}, []);
return (
<div
className={classNames('header-inner__main-search-slide', { open: props.visibleSearchBar })}
ref={slideRef}>
<input ref={inputRef}
disabled={disabled}
className='header-inner__main-search-slide-field' />
<button
onClick={() => { props.setVisibleSearchBar(false) }}
className='header-inner__main-search-slide-close'> CLOSE
</button>
</div >
)
用你的sanbox玩过,在这里它工作得很好-https://codesandbox.io/s/ecstatic-buck-d2rgx
所以你的问题就在这里:
const callback = () => {
setDisabled(false);
inputRef.current.focus();
}
每当某个过渡结束时,您都在设置焦点。但这是不正确的,你必须只在";打开";过渡结束。这一点很重要,因为浏览器会自动滚动到焦点元素,这就是在这种情况下发生的事情,你隐藏了输入,但随后聚焦了它,所以浏览器"滚动的";它回来了。
这里有一个固定版本:
if (slideRef.current.classList.contains("open")) {
inputRef.current.focus();
}
为什么我在这里不使用props
——因为,你的useEffect
只会在第一次渲染时执行,如果我在这里使用props
,我会使用传递给组件的第一个道具(因为闭包(。如果你不想检查classList
,另一个选择是在这里使用state(将"打开"标志移动到state(