【问题标题】:ReactJS: Go to anchor link in HTML with react router dom only after the full page loadReactJS:仅在整个页面加载后才使用反应路由器 dom 转到 HTML 中的锚链接
【发布时间】:2021-08-05 13:10:27
【问题描述】:

我有一个使用 React Router 定义 URL 的 React 应用:

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>
  );
};

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

我有一个组件可以返回有问题的手风琴,它们都有一个 id:

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

export default CategoryDisplay;

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

如何在页面加载后才滚动到元素?

【问题讨论】:

    标签: javascript reactjs react-router react-router-dom


    【解决方案1】:

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

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

    注意事项:

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

    【讨论】:

    • 在我将函数更改为将锚点更改为const anchor = window.location.hash.split("#")[1]; 后效果很好,谢谢!
    • 感谢指正;我更新了我的代码以正确获取锚点。不客气。
    【解决方案2】:

    不知道我理解的对不对。

    我想,你应该做一个等待一切完成的功能。

    但是,如果您在一切正常时无法准确把握时间, 你可以使用技巧。

    示例:

        const CategoryDisplay: React.FC<Props> = (props) => {
            ...
            const [accordionId, setAccordionId] = useState("");
            useEffect(()=>{
              // this component mounted
              ...
              setTimeout(()=>{
                // do something
                setAccordionId(`category-${accordion.id}`);
              },0);
            }, []);
            return (
              <>
                <Accordion
                  id={accordionId}/>
              </>
            );
        };
    

    这肯定会在组件安装后在框架中运行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-11-02
      • 2017-12-08
      • 2022-01-16
      • 1970-01-01
      • 2022-01-01
      • 2015-11-30
      • 2022-10-15
      相关资源
      最近更新 更多