Javascript 如何确保一次仅打开/展开一个面板?

Javascript 如何确保一次仅打开/展开一个面板?,javascript,reactjs,user-interface,collapse,expand,Javascript,Reactjs,User Interface,Collapse,Expand,这是一个组件/功能,它是一个可以通过按钮扩展的卡只不过是一个图像组件。必须使用它,因为图像是svg import React, { useState, useRef } from "react"; import Rating from "@material-ui/lab/Rating"; import Icon1 from "../test.jpeg"; import Viewmore from "./Viewmore&quo

这是一个组件/功能,它是一个可以通过按钮扩展的卡<代码>只不过是一个图像组件。必须使用它,因为图像是svg

import React, { useState, useRef } from "react";
import Rating from "@material-ui/lab/Rating";
import Icon1 from "../test.jpeg";
import Viewmore from "./Viewmore";

function Acc(props) {
  const [value, setValue] = React.useState(2);

  const content = useRef(null);

  const [setActive, setActiveState] = useState("");
  const [setHeight, setHeightState] = useState("160px");
  const [setRotate, setRotateState] = useState("icon");

  function toggleAccordion() {
    setActiveState(setActive === "" ? "active" : "");
    setHeightState(
      setActive === "active" ? "160px" : `${content.current.scrollHeight}px`
    );
    setRotateState(setActive === "active" ? "icon" : "icon rotate");
  }

  return (
    <div className="accordian" id={props.id}>
      <div className="accordianHeading">
        <div
          className="container"
          ref={content}
          style={{ maxHeight: `${setHeight}` }}
        >
          <img src={Icon1} className="postimg" />

          <div className="title">
            Nulla adipisicing do ea qui enim id cillum reprehenderit aliquip
            nostrud sint fugiat.
          </div>
          <div className="namedate">asdfasdf | 10th April 2021</div>
          <div classname="content">
            <p>
              Aliquip duis excepteur non ullamco eiusmod cillum cupidatat non
              officia laborum esse tempor est nisi. Aute amet irure ex proident
              commodo reprehenderit cupidatat deserunt dolor eu. Culpa elit
              officia sit id reprehenderit nisi amet tempor reprehenderit fugiat
              sint irure. Laborum pariatur nisi amet minim eiusmod ad occaecat
              ipsum aliquip. Aute dolore culpa ad minim voluptate. Lorem in qui
              pariatur nostrud in velit ad sunt irure mollit commodo. Sit
              voluptate occaecat cupidatat dolor veniam aute amet sit ea
              consequat et voluptate id.
            </p>
          </div>
        </div>
      </div>
      <div className="accordianContent">
        <div className="foot">
          <Rating defaultValue={0} precision={1} />
          <button className="button" onClick={toggleAccordion}>
            <Viewmore className={`${setRotate}`} width={20} fill={"777"} />
          </button>
        </div>
      </div>
    </div>
  );
}

export default Acc;
import React,{useState,useRef}来自“React”;
从“@material ui/lab/Rating”导入评级;
从“./test.jpeg”导入Icon1;
从“/Viewmore”导入Viewmore;
功能Acc(道具){
const[value,setValue]=React.useState(2);
const content=useRef(null);
const[setActive,setActiveState]=useState(“”);
常数[setHeight,setHeightState]=useState(“160px”);
常量[setRotate,setRotateState]=使用状态(“图标”);
函数toggleAccordion(){
setActiveState(setActive==“”?“活动”:“”;
设置高度状态(
setActive==“active”?“160px”:“${content.current.scrollHeight}px`
);
setRotateState(setActive==“活动”?“图标”:“图标旋转”);
}
返回(
我不知道该怎么做
诺斯特鲁德圣福吉亚。
asdfasdf | 2021年4月10日

这是一个例外,非乌拉姆科埃乌斯莫德铜合金
临时劳工局
这是一个很好的例子
临时行政长官
临时小型实验室
自相矛盾,自相残杀,自相残杀,自相残杀
坐在我的房间里
静脉或坐位的呕吐物
consequeat和voluptate id。

); } 导出默认Acc;
单击该按钮时,它将设置3个正在运行的进程。首先是激活状态,触发激活状态。这将触发一个活动的css类并旋转按钮图标

下面是路由到ReactDOM的App.js

import React, { useState } from "react";
import "./App.css";
import Acc from "./components/Acc";

function App() {
  return (
    <div className="App">
      <Acc />
      <Acc />
      <Acc />
      <Acc />
      <Acc />
      <Acc />
      <Acc />
      <Acc />
    </div>
  );
}

export default App;
import React,{useState}来自“React”;
导入“/App.css”;
从“/components/Acc”导入Acc;
函数App(){
返回(
);
}
导出默认应用程序;

如何确保一次只打开一张
卡?

有几种不同的方法可以做到这一点,但下面是我的建议

父卡(
App
)的状态为活动卡。它传给每个孩子

  • 不管它是否处于活动状态
  • 一个
    onToggle
    回调,让家长知道它单击了什么
  • 孩子正在监听其状态(
    active
    )上的(
    useffect
    ),并相应地更新UI

    App.js



    您也可以使用上下文,但我相信这是一种更简单的方法。

    这真的很好!但是你如何让它对一个不确定数量的卡工作。。。还有内容不同的卡片?rn它只是一次又一次地映射完全相同的卡片,但是如果我们必须重复调用它,我们如何注入内容呢?是的。这只是你的一个例子:)我已经更新了codesandbox,所以现在内容是“动态的”(来自)。显然,这不完全是您的情况,但它演示了过程。哦,好吧,那么有两件事:1)是否可以将{content}添加到,而不是从cards.json获取?这对于我的用例来说更有意义。2) 触发toggle()时,它会相应地更改状态,但当点击另一张卡的另一个切换时,前一个切换将关闭,但不会更改回任何其他状态?例如:我有一个活跃的状态。。。因此,当卡片打开时,它会稍微着色。当我关闭同一张卡时,色调消失,但当我单击另一张卡时,触发toggle(),色调和处于“活动”状态的所有内容都不会改变。这是完整的<代码>文本是您正在查找的从父级传递的内容。目前它来自于
    cards.json
    ,但您可以用任何其他方式替换此逻辑(如在javascript中生成或从服务器/api获取)。2.情况已经如此。当
    活动时,Acc组件正在“侦听”并更新其他组件的状态(如).你还想改变哪些州?如果有什么不清楚的,让我们
    
    const cards = [1, 2, 3, 4, 5, 6, 7, 8];
    
    export default function App() {
      const [active, setActive] = useState();
      const onToggle = (id) => {
        setActive(id === active ? null : id);
      };
      return (
        <div className="App">
          {cards.map((card) => (
            <Acc
              key={card}
              id={card}
              onToggle={onToggle}
              active={card === active}
            />
          ))}
        </div>
      );
    }
    
    useEffect(() => {
      setHeightState(active ? `${content.current.scrollHeight}px` : "160px");
      setRotateState(active ? "icon" : "icon rotate");
    }, [active]);
    function toggleAccordion() {
      onToggle(id);
      // setActiveState(setActive === "" ? "active" : "");
      // setHeightState(
      //   setActive === "active" ? "160px" : `${content.current.scrollHeight}px`
      // );
      // setRotateState(setActive === "active" ? "icon" : "icon rotate");
    }