簡體   English   中英

如何引用子組件內的 DOM 元素? [反應JS]

[英]How to refer to a DOM element inside a child component? [ReactJS]

我有這個 Header 組件,其中有許多鏈接組件,如下所示。 我根據 url 路徑有條件地渲染組件。 我想將“活動”的 CSS class 添加到適當的鏈接,這將使用戶知道哪個是活動鏈接。

Header.tsx

import * as React from 'react';
import { Link } from './Link';

export const Header: React.FC = () => {
  const [activeLink, setActiveLink] = React.useState<HTMLAnchorElement | null>(
    null
  );

  React.useEffect(() => {
    activeLink?.classList.add('active');

    return () => activeLink?.classList.remove('active');
  }, [activeLink]);

  return (
    <div className="ui secondary pointing menu">
      <div className="ui container">
        <Link href="/" className="item" setActiveLink={setActiveLink}>
          Accordion
        </Link>
        <Link href="/search" className="item" setActiveLink={setActiveLink}>
          WikiSearch
        </Link>
        <Link href="/translate" className="item" setActiveLink={setActiveLink}>
          Translate
        </Link>
      </div>
    </div>
  );
};

鏈接.tsx

import * as React from 'react';

type Props = {
  href: string;
  className: string;
  children: string;
  setActiveLink: React.Dispatch<React.SetStateAction<HTMLAnchorElement | null>>;
};

export const Link: React.FC<Props> = (props) => {
  const { href, className, children, setActiveLink } = props;

  const onClick = (event: React.MouseEvent) => {
    if (event.metaKey || event.ctrlKey) return;

    setActiveLink(event.target as HTMLAnchorElement);
    event.preventDefault();
    window.history.pushState({}, '', href);
    const navEvent = new PopStateEvent('popstate');
    window.dispatchEvent(navEvent);
  };

  return (
    <a href={href} className={className} onClick={onClick}>
      {children}
    </a>
  );
};

我嘗試通過使用 activeLink state 來實現它,它將保持活動鏈接,並且只有在您單擊某個鏈接時才能正常工作,但在第一次渲染時,沒有鏈接組件具有活動的 class 。 我將 useState 設置為 null 因為我不知道如何引用第一個鏈接組件。

理想情況下,我想將 activeLink state 初始化為第一個子鏈接組件內的錨元素。 因此,在第一次渲染時,默認情況下,第一個鏈接組件是活動鏈接。

在香草JS中,我可以簡單地做類似的事情

links = document.querySelector('a.item');
links.forEach(link => link.classList.remove('active'));

然后假設我可以訪問活動鏈接 dom 元素

activeLink.classList.add('active')

我可以將活動 class 添加到 html 中的第一個錨標簽

<a href='something' class='active item'> some text </a>

那么我將如何在 React 中實現相同的功能呢? 請就我應該如何處理這個問題或我做錯了什么提出一些想法。

正如@Rohit 所建議的,我嘗試將 activeLink state 更改為將 currentPath 存儲為 state ,然后檢查 href 屬性,結果完美。

路由器.tsx

import * as React from 'react';
import { Link } from './Link';

export const Header: React.FC = () => {
  const [currentPath, setCurrentPath] = React.useState(
    window.location.pathname
  );

  React.useEffect(() => {
    const onURLChange = () => setCurrentPath(window.location.pathname);

    window.addEventListener('popstate', onURLChange);
    return () => window.removeEventListener('popstate', onURLChange);
  }, []);

  const getClassName = (path: string) => {
    return currentPath === path ? 'active item' : 'item';
  };

  return (
    <div className="ui secondary pointing menu">
      <div className="ui container">
        <Link href="/" className={getClassName('/')}>
          Accordion
        </Link>
        <Link href="/search" className={getClassName('/search')}>
          WikiSearch
        </Link>
        <Link href="/translate" className={getClassName('/translate')}>
          Translate
        </Link>
      </div>
    </div>
  );
};

鏈接.tsx

import * as React from 'react';

type Props = {
  href: string;
  className: string;
  children: string;
};

export const Link: React.FC<Props> = (props) => {
  const { href, className, children } = props;

  const onClick = (event: React.MouseEvent) => {
    if (event.metaKey || event.ctrlKey) return;

    event.preventDefault();
    window.history.pushState({}, '', href);
    const navEvent = new PopStateEvent('popstate');
    window.dispatchEvent(navEvent);
  };

  return (
    <a href={href} className={className} onClick={onClick}>
      {children}
    </a>
  );
};

這就像一個魅力。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM