WAI-ARIA 属性需要一个唯一的 id,但是这个反应组件可能会被创建多次

问题描述 投票:0回答:1

我正在尝试创建一个带有 WAI-ARIA 属性的 Accordion 组件,但是,一些元素需要引用一个唯一的 id。在这种情况下,手风琴的内容 (

accordion__content
) 必须有一个唯一的 id,由按钮的属性
aria-controls
.

引用

由于该组件可能会在页面中的不同位置多次使用,因此使用“any-id”作为 id 是行不通的。

type AccordionProps = {
  children: ReactNode;
  label: string;
};

export const Accordion = ({ label, children }: AccordionProps) => {
  const { isContentShowing, setIsContentShowing } = useAccordion();

  return (
    <div className="accordion" aria-label={`${label} Accordion`} data-testid="accordion">
      <button
        className="accordion__button"
        onClick={setIsContentShowing}
        aria-expanded={isContentShowing}
        aria-controls="UNIQUE-ID"
      >
        <span className="accordion__text">{label}</span>
        <AccordionArrowIcon isContentShowing={isContentShowing} />
      </button>
      {isContentShowing && (
        <div className="accordion__content" id="UNIQUE-ID" aria-hidden={!isContentShowing}>
          {children}
        </div>
      )}
    </div>
  );
};

一个选择是生成一个随机 id 并将该 id 分配给属性,或者我们也可以将 id 作为 prop。有什么推荐的方法吗?

reactjs accessibility wai-aria
1个回答
0
投票

当我过去遇到这样的问题时,我已经为组件生成了一个 uuid。这将使您的代码像这样:

import React from "react";
// This is the library I'd use, but feel free to make up the ID however you want
import { uuid } from 'uuidv4';

type AccordionProps = {
  children: ReactNode;
  label: string;
};

export const Accordion = ({ label, children }: AccordionProps) => {
  const { isContentShowing, setIsContentShowing } = useAccordion();
  // Note that the ID will be regenerated on every re-render, but will still stay internally consistent
  const id = uuid();

  return (
    <div className="accordion" aria-label={`${label} Accordion`} data-testid="accordion">
      <button
        className="accordion__button"
        onClick={setIsContentShowing}
        aria-expanded={isContentShowing}
        aria-controls={id}
      >
        <span className="accordion__text">{label}</span>
        <AccordionArrowIcon isContentShowing={isContentShowing} />
      </button>
      {isContentShowing && (
        <div className="accordion__content" id={id} aria-hidden={!isContentShowing}>
          {children}
        </div>
      )}
    </div>
  );

此外,您的

aria-hidden
没有做任何事情。逻辑上没有任何意义,因为当内容不显示时元素不存在。

© www.soinside.com 2019 - 2024. All rights reserved.