I want to send mails with links to my faq-site, like http://www.test.com/faq#lorem_ipsum.
But my faq-site is made in react with multiple accordion components.
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>
);
};
I want that, when the user clicks on the link with anchor and jumps to the specific accordion AND the expand it. But i can't figure out, how to identify the accordion i'm jumping to. With plain javascript it's easy, but I can't find a solution with React.
Hope, that somebody could help me.
CodePudding user response:
As described in the mui documentation, you need to use a controlled accordion, using a state.
First, add a state to keep the name/id of the open accordion.
const [expanded, setExpanded] = useState(false);
Then, change you update function in order to grab the hash from the URL, check if a matching question exists inside your array, set the related accordion component as expanded, and finally scroll to it.
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();
}
}
}, []);
You also need to add an handler for clicks on the controlled accordion, to update the state with the name of the clicked accordion.
const handleChange = (panel) => (event, isExpanded) => {
setExpanded(isExpanded ? panel : false);
};
Finally, change the JSX code in order to use this logic.
{faqQuestions.map((question) => (
<Accordion
key={question.accordionId}
id={question.accordionId}
expanded={expanded === question.accordionId}
onChange={handleChange(question.accordionId)}>
// ... your accordion content
</Accordion>
))}