抓住 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>
))}