我的 React 應用程式中有一個手風琴組件。用戶可以向該手風琴添加專案。現在,當用戶單擊按鈕將專案添加到手風琴時,我希望新添加的手風琴專案自動打開。這是一個顯示我的問題的代碼和框。
要打開和關閉手風琴,我使用了一些狀態:const [clicked, setClicked] = useState("0");.
accordionItem單擊an 時,將呼叫以下函式:
const handleToggle = (index) => {
if (clicked === index) {
return setClicked("0");
}
setClicked(index);
};
在我的 codeandbox 演示中,我使用了一系列問題和答案,accordionItems并回圈瀏覽它們。所以我認為我所要做的就是使用該setClicked函式將clicked狀態設定為等于 faqs 陣列的長度減 1 以打開正確的手風琴,但這并沒有像預期的那樣作業......
參考代碼
Accordion.jsx:
import AccordionItem from "./AccordionItem";
import { useState } from "react";
export default function Accordion() {
const initialFaqs = [
{
question: "Lorem ipsum dolor sit amet?",
answer:
"Tenetur ullam rerum ad iusto possimus sequi mollitia dolore sunt quam praesentium. Tenetur ullam rerum ad iusto possimus sequi mollitia dolore sunt quam praesentium.Tenetur ullam rerum ad iusto possimus sequi mollitia dolore sunt quam praesentium."
},
{
question: "Dignissimos sequi architecto?",
answer:
"Aperiam ab atque incidunt dolores ullam est, earum ipsa recusandae velit cumque. Aperiam ab atque incidunt dolores ullam est, earum ipsa recusandae velit cumque."
},
{
question: "Voluptas praesentium facere?",
answer:
"Blanditiis aliquid adipisci quisquam reiciendis voluptates itaque."
}
];
const [faqs, setFaqs] = useState(initialFaqs);
const [clicked, setClicked] = useState("0");
const handleToggle = (index) => {
if (clicked === index) {
return setClicked("0");
}
setClicked(index);
};
const addFaq = () => {
let newFaq = [...faqs];
newFaq.push({
question: "This accordion item should automatically open",
answer:
"Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur."
});
setFaqs(newFaq);
//I want to open the accordion of the item that is just openend.
//Currently, setting the clicked state equal to the length of the faqs gives an error.
//Setting clicked equal to faqs.length - 1 does not open the newly added faq...
//How to solve?
setClicked(faqs.length);
};
return (
<div>
<ul className="accordion">
{faqs.map((faq, index) => (
<AccordionItem
onToggle={() => handleToggle(index)}
active={clicked === index}
key={index}
faq={faq}
/>
))}
</ul>
<button onClick={() => addFaq()} className="add-faq-btn">
Add question
</button>
</div>
);
}
AccordionItem.jsx:
import { useRef } from "react";
export default function AccordionItem({ faq, active, onToggle }) {
const contentEl = useRef();
const { question, answer } = faq;
return (
<li className={`accordion_item ${active ? "active" : ""}`}>
<button className="button" onClick={onToggle}>
{question}
<span className="control">{active ? "—" : " "} </span>
</button>
<div
ref={contentEl}
className="answer_wrapper"
style={
active
? { height: contentEl.current.scrollHeight }
: { height: "0px" }
}
>
<div className="answer">{answer}</div>
</div>
</li>
);
}
uj5u.com熱心網友回復:
你的問題很少。
一種是您必須newFaq在添加期間使用以下內容(因為狀態變數不會立即更新):
setClicked(newFaq.length - 1);
修復它后,您將收到另一個錯誤。那是因為您試圖ref在style物件中渲染期間訪問DOM 元素:由于組件尚未放置在 DOM 上,因此ref為 null。你將需要這樣的東西:
React.useEffect(() => {
setHeight(contentEl.current.scrollHeight);
}, []);
注意:老實說,我不確定上面 useEffect 哪個是正確的依賴項,如果我們這樣使用它,它將始終使用初始高度。如果某些專案的高度之后沒有改變,這可能沒問題。
并height在風格中使用
style={active ? { height } : { height: "0px" }}
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/343820.html
標籤:javascript 反应 反应钩子 jsx
