锚点是通过在界面中增加一些特征(比如 id),然后在 URL 地址后面加上 #id 就可以访问到指定页面的指定位置,这样可以让我们快速跳转到页面的某个位置,但是在 react-router 中这种方法遇到了问题,因为 react-router 会把 # 当做是 hash 来处理。导致即使跳转到指定页面后,# 后面的锚点也不生效。针对这个问题,在 react-router 的一个 issue 中大家也展开了激烈的讨论。以下是我看过以后整理的几种解决办法。
只有某些页面需要
当只有某些页面需要使用锚点的时候,可以在访问到该页面后使用 react 生命周期中 componentDidMount 阶段来判断 # 后面的字符串,然后使用 dom 操作取到这个字符串所属的 dom,然后滚动到该位置。具体代码如下:
1 | componentDidMount() { |
说不准哪些页面会使用
以上方法适用于具有生命周期的 react component,而且是在组件的生命周期中实现这个功能,若需要所有页面都实现这个功能,明显我们不可能在所有 component 中都增加这个方法。这就产生另外一个方案,就是在 Router 的 onUpdate 函数中实现该功能。onUpdate 函数在路由跳转后会被调用一次,如下所示:
1 | import React from 'react'; |
当地址改变后,hashLinkScroll 会被调用,函数内部实现原理与上面的原理是一样的,拿到 # 后面的 id 并找到指定 dom,然后滚动到该 dom 的位置。
总结
两种方案各有优劣,可以根据自己的情况来选择使用。