如何确保一次只有 1 个面板 open/expanded?
How can I make sure only 1 panel is open/expanded at a time?
这里是component/function,这是一张可以用按钮展开的卡片。 <Viewmore>
只不过是一个图像组件。不得不使用它,因为图像是 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;
单击该按钮时,它会启动 3 个进程。首先是触发活动状态的活动。这会触发活动 css class 并旋转按钮图标。
这是路由到 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;
如何确保一次只打开 1 张 <Acc />
卡片?
有一些不同的方法可以做到这一点,但这是我的建议。
parent(App
)有一个状态是活动卡。它传递给每个 child
- 是否激活
- 一个
onToggle
回调让 parent 知道它点击了。
child 正在监听 (useEffect
) 其状态 (active
) 并相应地更新 UI。
App.js
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>
);
}
Acc.js(仅区别)
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");
}
https://codesandbox.io/s/cranky-cherry-5x9xx?file=/src/App.js
您也可以使用 Context,但我认为这是一种更简单的方法。
这里是component/function,这是一张可以用按钮展开的卡片。 <Viewmore>
只不过是一个图像组件。不得不使用它,因为图像是 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;
单击该按钮时,它会启动 3 个进程。首先是触发活动状态的活动。这会触发活动 css class 并旋转按钮图标。
这是路由到 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;
如何确保一次只打开 1 张 <Acc />
卡片?
有一些不同的方法可以做到这一点,但这是我的建议。
parent(App
)有一个状态是活动卡。它传递给每个 child
- 是否激活
- 一个
onToggle
回调让 parent 知道它点击了。
child 正在监听 (useEffect
) 其状态 (active
) 并相应地更新 UI。
App.js
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>
);
}
Acc.js(仅区别)
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");
}
https://codesandbox.io/s/cranky-cherry-5x9xx?file=/src/App.js
您也可以使用 Context,但我认为这是一种更简单的方法。