[英]Using Reactstrap: How to toggle only one Collapse at a time?
我正在使用 Reactstrap 打開和折疊多張卡片。 一旦打開,它們就會保持打開狀態,並且由於我計划使用更多(用於文章),這將是一團糟。 一旦我點擊一個按鈕並打開一張卡片,我希望其他人關閉,所以一次只顯示一張卡片。 我怎樣才能做到這一點?
const [isOpenInfo, setIsOpenInfo] = useState(false);
const toggleInfo = () => setIsOpenInfo(!isOpenInfo);
const [isOpenArticle1, setIsOpenArticle1] = useState(false);
const toggleArticle1 = () => setIsOpenArticle1(!isOpenArticle1);
const [isOpenArticle2, setIsOpenArticle2] = useState(false);
const toggleArticle2 = () => setIsOpenArticle2(!isOpenArticle2);
在我的菜單中,我有一個“更多信息”按鈕,單擊時會打開折疊文章列表,單擊每個標題時會打開文章(但我只想一次打開一篇文章)。 所以這就像崩潰中的崩潰......
<Button className="info-button" color="primary" onClick={toggleInfo}>
More Info
</Button>
<Collapse isOpen={isOpenInfo}>
<Card className="card">
<CardBody className="card-body">
<div className="section section-articles">
<div className="articles-buttons">
<Button
className="article2-button"
color="primary"
onClick={toggleArticle2}
>
<h3>Article 2</h3>
</Button>
<Button
className="article1-button"
color="primary"
onClick={toggleArticle1}
>
<h3>Article 1</h3>
</Button>
</div>
<Collapse isOpen={isOpenArticle2}>
<Card className="card">
<CardBody className="card-body">
<Article2 />
</CardBody>
</Card>
</Collapse>
<Collapse isOpen={isOpenArticle1}>
<Card className="card">
<CardBody className="card-body">
<Article1 />
</CardBody>
</Card>
</Collapse>
</div>
</CardBody>
</Card>
</Collapse>
您可以創建一個包含所有文章的默認變量,並使用它來設置 state。 為所有可折疊文件創建一個 state 變量。
const DEFAULT_ARTICLES = {
article1: false,
article2: false,
};
const [articles, setArticles] = useState(DEFAULT_ARTICLES);
const toggleArticle = (key) => setArticles({
...DEFAULT_ARTICLES,
[key]: true,
});
在您的渲染 function 上使用鍵打開折疊並切換折疊。
<Collapse isOpen={isOpenInfo}>
<Card className="card">
<CardBody className="card-body">
<div className="section section-articles">
<div class="articles-buttons">
<Button
className="article2-button"
color="primary"
onClick={() => toggleArticle('article2')}
>
<h3>Article 2</h3>
</Button>
<Button
className="article1-button"
color="primary"
onClick={() => toggleArticle('article1')}
>
<h3>Article 1</h3>
</Button>
</div>
<Collapse isOpen={articles['article1']}>
<Card className="card">
<CardBody className="card-body">
<Article2 />
</CardBody>
</Card>
</Collapse>
<Collapse isOpen={articles['article2']}>
<Card className="card">
<CardBody className="card-body">
<Article1 />
</CardBody>
</Card>
</Collapse>
</div>
</CardBody>
</Card>
</Collapse>
您可以使用一個 state 來控制所有折疊。
const [openedCollapse, setOpenedCollapse] = useState("");
const openCollapse = e => { // this is the button onClick handler
setOpenedCollapse(e.target.dataset.collapse);
};
然后你的 jsx 看起來像這樣:
<Button
className="article1-button"
color="primary"
data-collapse="article1" // A dataset param
onClick={openCollapse}>
<h3>Article 1</h3>
</Button>
<Collapse isOpen={openedCollapse === "article1"}>
<Card className="card">
<CardBody className="card-body">
<Article2 />
</CardBody>
</Card>
</Collapse>
您可以在切換More Info
Collapse
時使用 object 作為 state 和回調 function,然后使用一個簡單的字符串來確定在主Button
內部打開時應該打開哪個文章。
例如,更新主折疊是否打開:
const toggleMoreInfo = () => {
setState(prevState => {
// this gives us access to the current state when setState is executed
// then we can inverse a boolean when the More Info button is clicked
return {
article: "", // resets the open article
moreInfoOpen: !prevState.moreInfoOpen // false => true || true => false
}
})
}
例如,更新應該打開哪篇文章:
const handleArticleOpen = (article) => {
setState((prevState) =>
return {
// keep whatever is in state as is by spreading it out (in this case, "moreInfoOpen" stays unchanged)
...prevState, //
// and just override the article with a passed in string
article
}));
};
在處理耦合的 state 時,我喜歡在單個狀態上使用對象,因為更容易使兩組 state 保持同步。 有關演示和完整代碼,請看下面...
import * as React from "react";
import { Button, Card, CardBody, Collapse } from "reactstrap";
import "./styles.css";
import "bootstrap/dist/css/bootstrap.min.css";
export default function App() {
const [state, setState] = React.useState({
articleOpen: "",
moreInfoOpen: false
});
const { article, moreInfoOpen } = state;
const toggleMoreInfo = () => {
setState((prevState) => ({
article: "",
moreInfoOpen: !prevState.moreInfoOpen
}));
};
const handleArticleOpen = (article) => {
setState((prevState) => ({
...prevState,
article
}));
};
return (
<div className="app">
<Button className="info-button" color="primary" onClick={toggleMoreInfo}>
More Info
</Button>
<Collapse isOpen={moreInfoOpen}>
<Card className="card">
<CardBody className="card-body">
<div className="section section-articles">
<div className="articles-buttons">
<Button
className="article2-button"
color="primary"
onClick={() => handleArticleOpen("2")}
>
<h3>Article 2</h3>
</Button>
<Button
className="article1-button"
color="primary"
onClick={() => handleArticleOpen("1")}
>
<h3>Article 1</h3>
</Button>
</div>
<Collapse isOpen={article === "2"}>
<Card className="card">
<CardBody className="card-body">
<div>Article 2</div>
</CardBody>
</Card>
</Collapse>
<Collapse isOpen={article === "1"}>
<Card className="card">
<CardBody className="card-body">
<div>Article 1</div>
</CardBody>
</Card>
</Collapse>
</div>
</CardBody>
</Card>
</Collapse>
</div>
);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.