问题描述
使用 reactstrap 文档,我创建了一个带有可折叠卡片的伪手风琴。我希望能够切换卡片,这样当我点击 list 2 的卡片标题时它会打开,如果我连续点击它会再次关闭。如果我点击列表 1,列表 2 应该会关闭,列表 1 应该会打开,正如预期的那样。
手风琴组件:
import React,{ Fragment,useState } from 'react';
import { Collapse,CardBody,Card,CardHeader } from 'reactstrap';
const Lists = () => {
const [isOpen,setIsOpen] = useState('');
const [lists,setLists] = useState([
{
_id: 'id_abc',item_names: ['item 1','item 2','item 3'],list_name: 'List 2',author_name: 'Samantha Samson',},{
_id: 'id_xyz','item 1','item 16'],list_name: 'List 1',author_name: 'John Johnson',]);
return (
<Fragment>
{lists.map((list) => (
<Card key={list._id}>
<CardHeader onClick={() => setIsOpen(list._id)}>
<h4>{list.list_name}</h4>
</CardHeader>
<Collapse isOpen={isOpen === list._id ? true : false}>
<CardBody>
<ul>
{list.item_names.map((item) => (
<li>{item}</li>
))}
</ul>
</CardBody>
</Collapse>
</Card>
))}
</Fragment>
);
const handletoggle = (id) => {
if(isOpen === id) {
setIsOpen('');
} else {
setIsOpen(id);
}
}
并给出标题:
onClick={handletoggle(list._id)}
但是这导致了太多的重新渲染/无限循环错误。
我还尝试了该函数的细微变化,但结果相同。
解决方法
你已经用这个修复了它:
const handleToggle = (id) => {
if (isOpen === id) {
setIsOpen("");
} else {
setIsOpen(id);
}
};
干得好!你犯错的地方就是这样称呼它:
onClick={handleToggle(list._id)}
这将在每次渲染时调用该函数,并且由于它更新状态变量,因此您将获得无限渲染。
应该是:
onClick={() => handleToggle(list._id)}
沙盒:https://codesandbox.io/s/hungry-jepsen-1ip0x?file=/src/App.js
仅供参考: 您可以将三元运算符简化为:
isOpen={isOpen === list._id}