首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >document.querySelector()在第一次单击React Router Link时始终返回null,但在单击后将正确返回

document.querySelector()在第一次单击React Router Link时始终返回null,但在单击后将正确返回
EN

Stack Overflow用户
提问于 2021-01-02 07:47:20
回答 1查看 330关注 0票数 0

我发现了一个关于React-Router和querySelector的问题。

我有一个包含用于导航的所有CustomLink组件的Navbar组件,以及一个侦听这些组件并根据当前活动组件显示动画的线动画。

代码语言:javascript
复制
// Navbar.tsx

import React, { useCallback, useEffect, useState, useRef } from "react";
import { Link, useLocation } from "react-router-dom";

import CustomLink from "./Link";

const Layout: React.FC = ({ children }) => {
  const location = useLocation();
  const navbarRef = useRef<HTMLDivElement>(null);
  const [pos, setPos] = useState({ left: 0, width: 0 });

  const handleActiveLine = useCallback((): void => {
    if (navbarRef && navbarRef.current) {
      const activeNavbarLink = navbarRef.current.querySelector<HTMLElement>(
        ".tdp-navbar__item.active"
      );

      console.log(activeNavbarLink);

      if (activeNavbarLink) {
        setPos({
          left: activeNavbarLink.offsetLeft,
          width: activeNavbarLink.offsetWidth,
        });
      }
    }
  }, []);

  useEffect(() => {
    handleActiveLine();
  }, [location]);

  return (
    <>
      <div className="tdp-navbar-content shadow">
        <div ref={navbarRef} className="tdp-navbar">
          <div className="tdp-navbar__left">
            <p>Todo+</p>
            <CustomLink to="/">About</CustomLink>
            <CustomLink to="/login">Login</CustomLink>
          </div>
          <div className="tdp-navbar__right">
            <button className="tdp-button tdp-button--primary tdp-button--border">
              <div className="tdp-button__content">
                <Link to="/register">Register</Link>
              </div>
            </button>
            <button className="tdp-button tdp-button--primary tdp-button--default">
              <div className="tdp-button__content">
                <Link to="/login">Login</Link>
              </div>
            </button>
          </div>
          <div
            className="tdp-navbar__line"
            style={{ left: pos.left, width: pos.width }}
          />
        </div>
      </div>
      <main className="page">{children}</main>
    </>
  );
};

export default Layout;
代码语言:javascript
复制
// CustomLink.tsx
import React, { useEffect, useState } from "react";
import { useLocation, useHistory } from "react-router-dom";

interface Props {
  to: string;
}

const CustomLink: React.FC<Props> = ({ to, children }) => {
  const location = useLocation();
  const history = useHistory();
  const [active, setActive] = useState(false);

  useEffect(() => {
    if (location.pathname === to) {
      setActive(true);
    } else {
      setActive(false);
    }
  }, [location, to]);

  return (
    // eslint-disable-next-line react/button-has-type
    <button
      className={`tdp-navbar__item ${active ? "active" : ""}`}
      onClick={(): void => {
        history.push(to);
      }}
    >
      {children}
    </button>
  );
};

export default CustomLink;

但它并不像我想要的那样工作。所以我打开Chrome Devtool并进行了调试,我意识到当我首先点击一个CustomLink时,来自NavbarquerySelector()将返回null。但如果我多次点击同一个CustomLink,它会正常返回,如下面的屏幕截图所示:

Error from Chrome Console

如何才能从第一次从querySelector()获得正确的返回?谢谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-01-02 08:48:09

因为handleActiveLine会在CustomLink.tsxsetActive(true)之前触发

CustomLink.tsx中添加回调

代码语言:javascript
复制
const CustomLink: React.FC<Props> = ({ onActive }) => {

  useEffect(() => {
    if (active) {
      onActive();
    }
  }, [active]);

}

Navbar.tsx

代码语言:javascript
复制
const Layout: React.FC = ({ children }) => {
  
  function handleOnActive() {
     // do your query selector here
  }

  // add onActive={handleOnActive} to each CustomLink
  return <CustomLink onActive={handleOnActive} />
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65534762

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档