使用Reactstrap:如何一次只切换一个塌陷?

2022-03-03 00:00:00 reactjs javascript jsx reactstrap
我正在使用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);
在我的菜单中,我有一个按钮&More Info&Quot;,当单击它时,它会打开折叠的文章列表,当单击每个标题时,它会打开文章(但我希望一次只打开一篇文章)。所以这就像是坍塌里面的坍塌…

<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>

解决方案

您可以在切换More Info折叠时将对象用作回调函数的状态,然后使用一个简单的字符串来确定当主Collapse打开并且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
    }));
  };

在处理耦合状态时,我喜欢使用对象而不是单独的状态,因为这样更容易使两组状态保持同步。有关演示和完整代码,请查看下面.


工作演示:


代码

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>
  );
}

相关文章