我在尝试使自己的自动完成组件反应时遇到问题。我创建了一个呈现结果的组件,并在其包装上设置max-height,我在输入元素上使用了onKeyDown事件来跟踪上/下键的按下。现在,我用它来标记活动项...但是当我设置的最大高度太小并且“活动项”超出div的高度限制时,在侧面有一个滚动条下去...我该如何解决?
import React, { useState, useEffect } from "react"
const Autocomplete = ({ options }) => {
const [activeOption, setActiveOption] = useState(4)
const [filteredOptions, setFilteredOptions] = useState([])
const [showOptions, setShowOptions] = useState(false)
const [userInput, setUserInput] = useState("")
useEffect(() => {
setShowOptions(userInput)
setFilteredOptions([
...options.filter(
option => option.toLowerCase().indexOf(userInput.toLowerCase()) > -1
)
])
setActiveOption(0)
}, [userInput])
const handleKeyDown = e => {
if (e.key === "ArrowDown") {
if (activeOption === filteredOptions.length - 1) return
setActiveOption(activeOption + 1)
}
if (e.key === "ArrowUp") {
if (activeOption === 0) return
setActiveOption(activeOption - 1)
}
}
return (
<>
<div className="search">
<input
type="text"
className="search-box"
value={userInput}
onChange={e => setUserInput(e.target.value)}
onKeyDown={handleKeyDown}
/>
<ul className="options">
{showOptions &&
filteredOptions.map((option, i) => (
<li className={activeOption === i ? `option-active` : ``} key={i}>
{option}
</li>
))}
</ul>
</div>
</>
)
}
export default Autocomplete
function App() {
return (
<div className="App">
<Autocomplete
options={[
"Alligator",
"Bask",
"Crocodilian",
"Death Roll",
"Eggs",
"Jaws",
"Reptile",
"Solitary",
"Tail",
"Wetlands"
]}
/>
</div>
)
}
.option-active {
font-weight: bold;
background: cornflowerblue;
}
.options {
height: 100px;
overflow: overlay;
}
您可以看到滚动条保持不变,并且不会随着li元素而下降...衷心的感谢!
scrollIntoView
方法。未经测试的代码:
// Use a ref container (we won't use `current`)
const elmRefs = useRef()
// Instead we build a custom ref object in each key of the ref for each option
useEffect(() => {
options.forEach(opt => elmRefs[opt] = {current: null}
}, [options])
// Effect that scrolls active element when it changes
useEffect(() => {
// This is what makes element visible
elmRefs[options[activeOption]].current.scrollIntoView()
}, [options, activeOption])
// In the "render" section, connect each option to elmRefs
<li className={activeOption === i ? `option-active` : ``} ref={elmRefs[option]} key={i}>
{option}
</li>
让我知道您的想法!