我正在React中构造一个看起来像这样的输入字段:
当单击“ x”(StyledCloseCircle
)时,文本将被清除,并且“ x”符号应消失。输入字段为焦点时,当前会在JavaScript中显示“ x”符号
export const Search = React.forwardRef((props, ref) => {
const [isFocused, setFocus] = useState(false);
const [isHovered, setHover] = useState(false);
return (
<InputContainer
onMouseEnter={() => setHover(true)}
onMouseLeave={() => setHover(false)}
>
<StyledInput
onFocus={() => setFocus(true)}
onBlur={() => setFocus(false)}
isHovered={isHovered}
ref={ref}
{...props}
/>
{isFocused && !props.value && (
<StyledMagnifyingGlass
isHovered={isHovered}
isFocused={isFocused}
onClick={props.onSearch}
/>
)}
{isFocused && props.value && (
<StyledCloseCircle onClick={() => console.log("THIS DOES NOT FIRE")} />
)}
{!isFocused && (
<StyledMagnifyingGlass
isHovered={isHovered}
isFocused={isFocused}
onClick={props.onSearch}
/>
)}
</InputContainer>
);
});
问题是,单击“ x”时,输入失去焦点,这将导致在下一个渲染中删除“ x”,并且不注册click
事件。但是,它确实会触发mousedown
事件。
因此,我的两个问题是:
mousedown
而不注册click
的操作顺序是什么?答案 0 :(得分:1)
您应该创建一个单独的状态来控制显示/隐藏“清除”按钮的位置。像现在一样显示onFocus
,但如果用户在输入容器之外单击或单击“清除”按钮,则将其隐藏。您还可以onBlur
隐藏它,但是如果用户使用键盘而不是鼠标,则可能会超时(500-1000ms)。
这是以下代码的CodeSnadbox example:
function App() {
const inputContainerRef = useRef();
const [value, setValue] = useState("");
const [showClear, setShowClear] = useState(false);
const onFocus = useCallback(() => {
setShowClear(true);
}, []);
const onClear = useCallback(() => {
setValue("");
setShowClear(false);
}, []);
const onOutsideClick = useCallback(e => {
// hide Clear button only if clicked outside of the container
if (!inputContainerRef.current.contains(e.target)) {
setShowClear(false);
}
}, []);
useLayoutEffect(
() => {
// set the listener only if we shown the Clear button and remove the listener once we hid it
if (showClear) {
document.addEventListener("click", onOutsideClick);
return () => document.removeEventListener("click", onOutsideClick);
}
},
[showClear] // re-invoke if the state changes
);
return (
<div className="App">
<div className="input-container" ref={inputContainerRef}>
<input
value={value}
onChange={e => {
setValue(e.target.value);
}}
className="input"
type="tetxt"
onFocus={onFocus}
/>
{showClear && (
<div className="clear" onClick={onClear}>
X
</div>
)}
</div>
</div>
);
}