抓住 url 片段并展开相关的手风琴,滚动到它
Grab the url fragment and expand the related accordion, scrolling to it
我想将带有 link 的邮件发送到我的常见问题解答站点,例如 http://www.test.com/faq#lorem_ipsum。
但我的常见问题解答站点是在与多个手风琴组件反应时制作的。
const faqQuestions = [
{
title: <h1 className="font-bold">question?</h1>,
content: (
<div className="px-4">
test
</div>
),
accordionId: 'lorem_ipsum',
},
]
const Faq = () => {
// const [isExpanded, setIsExpanded] = useState(false);
useLayoutEffect(() => {
const anchor = window.location.hash.split('#')[1];
if (anchor) {
const anchorEl = document.getElementById(anchor);
if (anchorEl) {
anchorEl.scrollIntoView();
}
}
}, []);
return (
<div className="container mx-auto px-10 lg:px-0">
<div className="py-6">
<p className="font-semibold text-3xl text-primary">Häufige Fragen</p>
</div>
<div className="pb-10">
{faqQuestions.map((question) => (
<Accordion key={Math.random()} id={question.accordionId}>
<AccordionSummary
expandIcon={<FontAwesomeIcon icon={faChevronDown} />}
aria-controls="panel1a-content"
>
<div>{question.title}</div>
</AccordionSummary>
<AccordionDetails>{question.content}</AccordionDetails>
</Accordion>
))}
</div>
</div>
);
};
我想要这样,当用户单击带有锚点的 link 并跳转到特定手风琴并将其展开时。但我无法弄清楚,如何识别我要跳到的手风琴。使用普通 javascript 很容易,但我找不到 React 的解决方案。
希望有人能帮助我。
如mui documentation所述,需要使用受控手风琴,使用状态。
首先,添加一个状态来保持打开手风琴的name/id。
const [expanded, setExpanded] = useState(false);
然后,更改更新函数以从 URL 中获取哈希,检查数组中是否存在匹配问题,将相关的手风琴组件设置为已展开,最后滚动到它。
useLayoutEffect(() => {
const anchor = window.location.hash.split('#')[1];
if (anchor) {
const accExists = faqQuestions.find(q => q.accordionId === anchor)
if (accExists) {
setExpandend(anchor);
const anchorEl = document.getElementById(anchor);
anchorEl.scrollIntoView();
}
}
}, []);
您还需要为受控手风琴的点击添加一个处理程序,以使用点击的手风琴的名称更新状态。
const handleChange = (panel) => (event, isExpanded) => {
setExpanded(isExpanded ? panel : false);
};
最后,更改 JSX 代码以使用此逻辑。
{faqQuestions.map((question) => (
<Accordion
key={question.accordionId}
id={question.accordionId}
expanded={expanded === question.accordionId}
onChange={handleChange(question.accordionId)}>
// ... your accordion content
</Accordion>
))}
我想将带有 link 的邮件发送到我的常见问题解答站点,例如 http://www.test.com/faq#lorem_ipsum。
但我的常见问题解答站点是在与多个手风琴组件反应时制作的。
const faqQuestions = [
{
title: <h1 className="font-bold">question?</h1>,
content: (
<div className="px-4">
test
</div>
),
accordionId: 'lorem_ipsum',
},
]
const Faq = () => {
// const [isExpanded, setIsExpanded] = useState(false);
useLayoutEffect(() => {
const anchor = window.location.hash.split('#')[1];
if (anchor) {
const anchorEl = document.getElementById(anchor);
if (anchorEl) {
anchorEl.scrollIntoView();
}
}
}, []);
return (
<div className="container mx-auto px-10 lg:px-0">
<div className="py-6">
<p className="font-semibold text-3xl text-primary">Häufige Fragen</p>
</div>
<div className="pb-10">
{faqQuestions.map((question) => (
<Accordion key={Math.random()} id={question.accordionId}>
<AccordionSummary
expandIcon={<FontAwesomeIcon icon={faChevronDown} />}
aria-controls="panel1a-content"
>
<div>{question.title}</div>
</AccordionSummary>
<AccordionDetails>{question.content}</AccordionDetails>
</Accordion>
))}
</div>
</div>
);
};
我想要这样,当用户单击带有锚点的 link 并跳转到特定手风琴并将其展开时。但我无法弄清楚,如何识别我要跳到的手风琴。使用普通 javascript 很容易,但我找不到 React 的解决方案。
希望有人能帮助我。
如mui documentation所述,需要使用受控手风琴,使用状态。
首先,添加一个状态来保持打开手风琴的name/id。
const [expanded, setExpanded] = useState(false);
然后,更改更新函数以从 URL 中获取哈希,检查数组中是否存在匹配问题,将相关的手风琴组件设置为已展开,最后滚动到它。
useLayoutEffect(() => {
const anchor = window.location.hash.split('#')[1];
if (anchor) {
const accExists = faqQuestions.find(q => q.accordionId === anchor)
if (accExists) {
setExpandend(anchor);
const anchorEl = document.getElementById(anchor);
anchorEl.scrollIntoView();
}
}
}, []);
您还需要为受控手风琴的点击添加一个处理程序,以使用点击的手风琴的名称更新状态。
const handleChange = (panel) => (event, isExpanded) => {
setExpanded(isExpanded ? panel : false);
};
最后,更改 JSX 代码以使用此逻辑。
{faqQuestions.map((question) => (
<Accordion
key={question.accordionId}
id={question.accordionId}
expanded={expanded === question.accordionId}
onChange={handleChange(question.accordionId)}>
// ... your accordion content
</Accordion>
))}