使用history React模块,如何解决a标签ESLint无障碍警告且不转按钮?
jsx-a11y/anchor-is-valid警告(不转按钮) 背景
我用history React模块管理会话历史,写了如下链接:
<a className="edit" onClick={() => { history.push(`/user/${this.props.match.params.id}/${i.slug}`); }} > Edit User </a>
这触发了ESLint的警告:
The href attribute is required for an anchor to be keyboard accessible. Provide a valid, navigable address as the href value. If you cannot provide an href, but still need the element to resemble a link, use a button and change it with appropriate styles. Learn more: https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/HEAD/docs/rules/anchor-is-valid.md jsx-a11y/anchor-is-valid
核心疑问
是否有办法不将超链接转为按钮即可解决该警告?(仓库内CSS复杂度高,转按钮工作量极大。)
另外,如果我添加href属性,如下所示,ESLint警告会消失,但history模块还能正常工作吗?
<a className="edit" href={`/user/${this.props.match.params.id}/${i.slug}`} //extra line onClick={() => { history.push(`/user/${this.props.match.params.id}/${i.slug}`); }} > Edit User </a>
不转按钮解决警告的两种方法
不用改按钮,有两个简单办法搞定ESLint警告:
- 方案一:加
href="#"并阻止默认行为
给a标签补上href="#",同时在点击事件里阻止默认跳转,既符合可访问性要求,又不影响history的使用:<a className="edit" href="#" onClick={(e) => { e.preventDefault(); history.push(`/user/${this.props.match.params.id}/${i.slug}`); }} > Edit User </a> - 方案二:加目标地址的
href并阻止默认行为
就是你设想的写法,但一定要加e.preventDefault()!不然浏览器会直接跳转刷新页面,history的客户端路由就失效了:<a className="edit" href={`/user/${this.props.match.params.id}/${i.slug}`} onClick={(e) => { e.preventDefault(); history.push(`/user/${this.props.match.params.id}/${i.slug}`); }} > Edit User </a>
关于history是否正常工作的问题
直接加href但不加阻止默认行为的话,浏览器会优先执行a标签的跳转逻辑,导致页面刷新,history的push方法就无法触发客户端路由了。必须加上e.preventDefault(),阻止页面刷新,这样history才能正常完成无刷新跳转。
额外优化提示
a标签默认支持键盘回车触发点击,但如果有特殊场景,可以显式添加tabIndex="0",确保元素能被键盘聚焦,进一步提升可访问性。
内容的提问来源于stack exchange,提问作者Nick

