React 生成传递给无障碍属性的唯一 ID

news/2024/7/15 17:30:56 标签: react.js, javascript, 前端

useId()

在组件的顶层调用 useId 生成唯一 ID:

import { useId } from 'react';  

function PasswordField() {  
const passwordHintId = useId();  
// ...
参数

useId 不带任何参数。

返回值

useId 返回一个唯一的字符串 ID,与此特定组件中的 useId 调用相关联。

注意事项
  • useId 是一个 Hook,因此你只能 在组件的顶层 或自己的 Hook 中调用它。你不能在内部循环或条件判断中调用它。如果需要,可以提取一个新组件并将 state 移到该组件中。
  • useId 不应该被用来生成列表中的 key。key 应该由你的数据生成。

用法

为无障碍属性生成唯一 ID

在组件的顶层调用 useId 生成唯一 ID:

import { useId } from 'react';

function PasswordField() {
  const passwordHintId = useId();
  // ...

你可以将 生成的 ID 传递给不同的属性:

<>
  <input type="password" aria-describedby={passwordHintId} />
  <p id={passwordHintId}>
</>

让我们通过一个例子,看看这个什么时候有用

aria-describedby 这样的 HTML 无障碍属性 允许你指定两个标签之间的关系。例如,你可以指定一个元素(比如输入框)由另一个元素(比如段落)描述。

在常规的 HTML 中,你会这样写:

<label>
  密码:
  <input
    type="password"
    aria-describedby="password-hint"
  />

</label>
<p id="password-hint">
  密码应该包含至少 18 个字符
</p>

然而,在 React 中直接编写 ID 并不是一个好的习惯。一个组件可能会在页面上渲染多次,但是 ID 必须是唯一的!不要使用自己编写的 ID,而是使用 useId 生成唯一的 ID。

import { useId } from 'react';

function PasswordField() {
  const passwordHintId = useId();
  
  return (
    <>
      <label>
        密码:
        <input
          type="password"
          aria-describedby={passwordHintId}
        />
      </label>
      <p id={passwordHintId}>
        密码应该包含至少 18 个字符
      </p>
    </>
  );
}

现在,即使 PasswordField 多次出现在屏幕上,生成的 ID 并不会冲突。

import { useId } from 'react';

function PasswordField() {
  const passwordHintId = useId();
  return (
    <>
      <label>
        密码:
        <input
          type="password"
          aria-describedby={passwordHintId}
        />
      </label>
      <p id={passwordHintId}>
        密码应该包含至少 18 个字符
      </p>
    </>
  );
}

export default function App() {
  return (
    <>
      <h2>输入密码</h2>
      <PasswordField />
      <h2>验证密码</h2>
      <PasswordField />
    </>
  );
}

在这里插入图片描述

为多个相关元素生成 ID

如果你需要为多个相关元素生成 ID,可以调用 useId 来为它们生成共同的前缀:

import { useId } from 'react';

export default function Form() {
  const id = useId();
  return (
    <form>
      <label htmlFor={id + '-firstName'}>名字:</label>
      <input id={id + '-firstName'} type="text" />
      <hr />
      <label htmlFor={id + '-lastName'}>姓氏:</label>
      <input id={id + '-lastName'} type="text" />
    </form>
  );
}

可以使你避免为每个需要唯一 ID 的元素调用 useId


为所有生成的 ID 指定共享前缀

如果你在单个页面上渲染多个独立的 React 应用程序,请在 createRoothydrateRoot 调用中将 identifierPrefix 作为选项传递。这确保了由两个不同应用程序生成的 ID 永远不会冲突,因为使用 useId 生成的每个 ID 都将以你指定的不同前缀开头。

index.html

<!DOCTYPE html>
<html>
  <head><title>My app</title></head>
  <body>
    <div id="root1"></div>
    <div id="root2"></div>
  </body>
</html>

App.js

import { useId } from 'react';

function PasswordField() {
  const passwordHintId = useId();
  console.log('生成的 ID:', passwordHintId)
  return (
    <>
      <label>
        密码:
        <input
          type="password"
          aria-describedby={passwordHintId}
        />
      </label>
      <p id={passwordHintId}>
        密码应该包含至少 18 个字符
      </p>
    </>
  );
}

export default function App() {
  return (
    <>
      <h2>输入密码</h2>
      <PasswordField />
    </>
  );
}

index.js

import { createRoot } from 'react-dom/client';
import App from './App.js';
import './styles.css';

const root1 = createRoot(document.getElementById('root1'), {
  identifierPrefix: 'my-first-app-'
});
root1.render(<App />);

const root2 = createRoot(document.getElementById('root2'), {
  identifierPrefix: 'my-second-app-'
});
root2.render(<App />);

在这里插入图片描述

useId – React 中文文档 (docschina.org)


http://www.niftyadmin.cn/n/5130647.html

相关文章

有一个带头结点的单链表L,设计一个算法使其元素递增有序

有一个带头结点的单链表L&#xff0c;设计一个算法使其元素递增有序 代码思路&#xff1a; 我这里懒得搞那个指针了&#xff0c;直接遍历一遍链表&#xff0c;把链表的元素复制到数组arr里面 对数组A进行一下排序&#xff0c;排完之后再把元素复制到L里面。 至于排序你用啥算…

低代码平台自动化办公--异行星低代码平台为例(一)

自动化操作 自动操作是可重复使用的组件&#xff0c;可在后台执行某种操作&#xff0c;如更新字段或发送电子邮件。创建自动操作后&#xff0c;将其添加到批准过程、工作流规则中。 字段更新​ 字段更新操作允许您自动更新字段值。您可以将字段更新与工作流规则、批准过程关…

EASEX绘制卡通头像

#include <stdio.h> #include <easyx.h> #include <iostream> #include <math.h> #define PI 3.14 // 1PI 180度 2PI 360度int main() {// 创建1024*1024的窗体initgraph(1024, 1024);// 将背景颜色设施为白色setbkcolor(WHITE);cleardevice();// to…

【Qt】窗口和对话框区别、主窗口和二级窗口区别、QMainWindow和QDialog区别

窗口和对话框&#xff08;Window and Dialog Widgets&#xff09; 未嵌入在父界面中的界面称为窗口。&#xff08;通常&#xff0c;窗口具有边框和标题栏&#xff0c;尽管也可以使用合适的窗口标志创建没有此类标志的窗口&#xff09;。 在Qt中&#xff0c;QMainWindow和QDial…

开源3D激光(视觉)SLAM算法汇总(持续更新)

目录 一、Cartographer 二、hdl_graph_slam 三、LOAM 四、LeGO-LOAM 五、LIO-SAM 六、S-LOAM 七、M-LOAM 八、livox-loam 九、Livox-Mapping 十、LIO-Livox 十一、FAST-LIO2 十二、LVI-SAM 十三、FAST-Livo 十四、R3LIVE 十五、ImMesh 十六、Point-LIO 一、Cartographer Cartog…

GPT的广泛应用会对互联网公司造成挑战吗?——探讨GPT在实际使用中的应用和影响

文章目录 前言GPT 技术的背景和发展历程GPT 技术对互联网行业的影响GPT 技术在互联网行业中的应用GPT 技术对于用户隐私和数据安全的威胁GPT 技术对于人类工作岗位的影响加强 AI 伦理和监管加强 AI 安全性和隐私保护推动 AI 创新和发展&#xff0c;避免过度依赖 AIGPT 技术是一…

亚信科技:发挥自我优势深入AIGC,并购整合高瞻远瞩致力未来路

【科技明说 &#xff5c; 重磅专题】 亚信科技在IT提供商领域中是一个低调的前行者&#xff0c;在全球通信及大型企业市场中扮演着重要的角色。对于近年来如火如荼AI方面的投入与研究&#xff0c;亚信科技是否也很重视呢&#xff1f; 事实上&#xff0c;是肯定的回答。 在我看…

Groovy安装开发环境

准备下载GDK并安装环境变量,跟安装JDK一模一样 https://groovy.apache.org/download.html