概览useId 能在服务端与客户端生成稳定一致的标识,避免 SSR 水合后出现不一致。通过该标识可将 label、描述与错误提示可靠关联到输入控件,满足可访问性要求并改善表单体验。基础关联import { useId, useState } from 'react'

export default function Field() {

const id = useId()

const [value, setValue] = useState('')

const hintId = `${id}-hint`

return (

<div>

<label htmlFor={id}>邮箱</label>

<input

id={id}

type="email"

value={value}

onChange={(e) => setValue(e.target.value)}

aria-describedby={hintId}

required

/>

<p id={hintId}>我们仅用于通知</p>

</div>

)

}

错误信息关联import { useId, useState } from 'react'

export function PasswordField() {

const id = useId()

const [error, setError] = useState<string | null>(null)

const errId = `${id}-error`

return (

<div>

<label htmlFor={id}>密码</label>

<input

id={id}

type="password"

aria-errormessage={errId}

aria-invalid={Boolean(error)}

onBlur={(e) => {

const v = e.target.value

setError(v.length < 8 ? '至少 8 个字符' : null)

}}

/>

{error && <p id={errId} role="alert">{error}</p>}

</div>

)

}

复合控件import { useId } from 'react'

export function RadioGroup() {

const gid = useId()

const labelId = `${gid}-label`

return (

<div role="radiogroup" aria-labelledby={labelId}>

<p id={labelId}>选择一个选项</p>

<label><input type="radio" name={gid} value="a" />A</label>

<label><input type="radio" name={gid} value="b" />B</label>

</div>

)

}

工程要点以 useId 为根派生子标识,避免重复或冲突。SSR 与 CSR 保持一致,避免因随机 id 导致水合差异。与表单状态结合,在错误出现时提供 ARIA 提示并维持焦点语义。验证与指标React:19.0+;Next.js:15.0+在 SSR 场景下不产生水合警告,读屏器能正确关联提示与错误信息

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论
立即
投稿

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部