如何使一个元素正确地重置其状态并在专注于输入的同时传递道具



我试图在安装元素时将焦点添加到输入字段上。我使用这个代码。当我按下标题上的按钮时,搜索栏就会出现,我会将类添加到其中打开,因为
希望我的搜索在转换的帮助下移动。搜索栏开始移动并到达其位置焦点被应用。很好。然后我点击";关闭";按钮来隐藏搜索栏并使其平滑回到它的位置(向后,隐藏起来(。到现在为止一切都好。因为在那之后,搜索栏就会出现即使我按下了关闭按钮,它也不会隐藏!我希望

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(

最新更新