我是ReactJS和react引导程序的新手。我的目标是当用户将鼠标悬停在下拉菜单上时打开它。我已经搜索过了,但它不起作用。我的解决方案是使用react钩子来存储和更新数组中"hoverItem"的当前状态是true还是false(Beacase我有2个下拉菜单,而不仅仅是1个(。
但它没有工作,并得到一个错误"错误:太多的重新渲染。React限制渲染的数量以防止无限循环">
<NavDropdown onMouseEnter={handleOpen(index)} onMouseLeave={handleClose(index)} show={isOpen[index]} title={item.title} id={item.id} key={item.id}>
{item.sub.map(element => { return (
<NavDropdown.Item href={element.url} key={element.id} onClick={handleClose}>
{element.item}
</NavDropdown.Item>
); })}
</NavDropdown>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
更新状态为:
const [isOpen, setIsOpen] = useState(() => {
//create an array with n-element and set all elements to false
return Array.apply(null, Array(MENU.length)).map(x => false);
});
const handleOpen = index => {
let temp = isOpen;
temp[index] = true;
setIsOpen(temp);
};
const handleClose = index => {
let temp = isOpen;
temp[index] = false;
setIsOpen(temp);
};
这个问题的重点是我不知道如何更新(修改(数组中的元素状态。请告诉我怎么做。谢谢你,很抱歉给我的英语带来不便。
第一个错误:onMouseEnter
和onMouseLeave
需要一个函数声明而不是调用,因为您调用了handleOpen(index)
,它会重新渲染,然后再次重新渲染,依此类推。。。修复错误:
onMouseEnter={(e) => handleOpen(index)}
第二个错误:
<NavDropdown.Item href={element.url} key={element.id} onClick={handleClose}>
这将使用一个事件调用handleClose,预期为index
,以修复:
onClick={e => handleClose(index) }
第三个错误:您的handleClose和handleOpen正在使用对旧状态的引用更新状态,需要一个新数组来修复:
const handleOpen = index => {
let temp = [...isOpen];
temp[index] = true;
setIsOpen(temp);
};
const handleClose = index => {
let temp = [...isOpen];
temp[index] = false;
setIsOpen(temp);
};
此外,您的isOpen
名称不明确,初始化也错误!
const [isOpen, setIsOpen] = useState(() => {
return Array.apply(null, Array(MENU.length)).map(x => false);
});
应该是
const [status, setStatus] = useState(MENU.map(x=> false));
总体您可以这样写:
const updateStatus = (value, index) => {
const clone = [...status];
clone[index] = value;
setStatus(clone);
}
<NavDropdown
onMouseEnter={e => updateStatus(true, index)}
onMouseLeave={e => updateStatus(false, index)}
show={status[index]}
title={item.title}
id={item.id}
key={item.id}
>
{item.sub.map(element =>
<NavDropdown.Item
href={element.url}
key={element.id}
onClick={e => updateStatus(false, index)}
>
{element.item}
</NavDropdown.Item>
)}
</NavDropdown>