如何使元素在关注输入的同时正确地重置其状态并传递道具
How to make an element correctly reset its state and pass props while focusing on the input
我尝试在安装元素时将焦点添加到输入字段。
我使用 this code。当我按下 Header 上的按钮时,搜索栏出现,我将其添加到 class 打开因为
希望我的搜索在过渡的帮助下移动。搜索栏开始移动并到达其位置,然后
焦点被应用。没关系。然后我点击“关闭”按钮隐藏搜索栏,它顺利
return 到它的位置(向后,隐藏)。到现在为止都还好。因为在那之后,搜索栏出现了
再次并没有隐藏,即使我按下了关闭按钮!我希望
onClick={() => { props.setVisibleSearchBar(false) }}
将隐藏我的搜索。顺便说一句,“开放”的风格也没有
当关闭 btn 后搜索意外出现时应用
单击(虽然搜索是
可见)。
Header.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
,其他选项是在此处使用状态(将 'open' 标志移动到状态)
我尝试在安装元素时将焦点添加到输入字段。
我使用 this code。当我按下 Header 上的按钮时,搜索栏出现,我将其添加到 class 打开因为
希望我的搜索在过渡的帮助下移动。搜索栏开始移动并到达其位置,然后
焦点被应用。没关系。然后我点击“关闭”按钮隐藏搜索栏,它顺利
return 到它的位置(向后,隐藏)。到现在为止都还好。因为在那之后,搜索栏出现了
再次并没有隐藏,即使我按下了关闭按钮!我希望
onClick={() => { props.setVisibleSearchBar(false) }}
将隐藏我的搜索。顺便说一句,“开放”的风格也没有 当关闭 btn 后搜索意外出现时应用 单击(虽然搜索是 可见)。
Header.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
,其他选项是在此处使用状态(将 'open' 标志移动到状态)