ReactJS:仅在完整页面加载后才使用react router dom转到HTML中的锚链接

sno*_*cat 2 javascript reactjs react-router react-router-dom

我有一个 React 应用程序,其中的 URL 使用 React Router 定义:

const App: React.FC = (): JSX.Element => {
  return (
    <Router>
      <Switch>
        <Redirect exact from="/" to="/rules" />
        <Route
          exact
          path={["/rules", "/rules/:placeId"]}
          component={LandingPage}
        />
        <Route
          exact
          path={["/route", "/route/:start/:end"]}
          component={RoutePage}
        />
      </Switch>
    </Router>
  );
};
Run Code Online (Sandbox Code Playgroud)

如果 url 包含这样的哈希部分,我想允许用户转到文档的特定手风琴部分/rules/someplace#accordion-3

我有一个返回相关手风琴的组件,它们都有一个 id:

const CategoryDisplay: React.FC<Props> = (props) => {
...
  return (
    <>
      <Accordion
        id={`category-${accordion.id}`}/>
    </>
  );
};

export default CategoryDisplay;
Run Code Online (Sandbox Code Playgroud)

当我打开带有锚点的 URL 时(就像/rules/someplace#accordion-3我已经在页面上一样),一切正常并且滚动到该元素。但是,在页面初始加载时,此行为不起作用。

仅在页面加载后我将如何滚动到该元素?

Jos*_*ley 6

我认为这个想法是在组件安装后使用效果滚动到适当的组件。也许是这样的:

React.useEffect(() => {
    const anchor = window.location.hash.slice(1);
    if (anchor) {
        const anchorEl = document.getElementById(anchor);
        if (anchorEl) {
            anchorEl.scrollIntoView();
        }
    }
}, []);
Run Code Online (Sandbox Code Playgroud)

笔记:

  • 我没有测试过这个。
  • useLayoutEffect 而不是 useEffect 可能会在这里提供更好的体验;有关详细信息,请参阅这篇文章
  • 我绕过 React 并使用 DOM。我通常会尽量避免这种情况,但由于这种逻辑是孤立的,并且本质上专注于浏览器 DOM 行为,因此我认为这是一个很好的用例(而不是通过与 React 组件进行更多交互来使代码复杂化。)
  • scrollIntoView 很方便,但还处于实验阶段;考虑改用scroll-into-view-if-needed NPM 包。