मेरे पास यह हैडर घटक है जिसमें नीचे दिखाए गए अनुसार इसके अंदर कई लिंक घटक हैं। मैं यूआरएल पथ के आधार पर सशर्त रूप से घटकों को प्रस्तुत कर रहा हूं। मैं उचित लिंक में 'सक्रिय' का एक सीएसएस वर्ग जोड़ना चाहता था जिससे उपयोगकर्ताओं को पता चल सके कि सक्रिय लिंक कौन सा है।

हैडर.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>
  );
};

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

मैंने एक सक्रिय लिंक स्थिति का उपयोग करके इसे लागू करने का प्रयास किया जो सक्रिय लिंक रखेगा और यह ठीक काम करता है जब आप किसी लिंक पर क्लिक करते हैं लेकिन पहले रेंडर पर, कोई लिंक घटक नहीं होता है जिस पर सक्रिय वर्ग होता है। मैंने उपयोगस्टेट को शून्य के रूप में सेट किया क्योंकि मुझे नहीं पता था कि पहले लिंक घटक को कैसे संदर्भित किया जाए।

आदर्श रूप से, मैं सक्रिय लिंक स्थिति को पहले बच्चे लिंक घटक के अंदर एंकर तत्व में प्रारंभ करना चाहता हूं। ताकि पहले रेंडर पर, पहला लिंक घटक डिफ़ॉल्ट रूप से सक्रिय लिंक हो।

वेनिला जेएस में मैं बस कुछ ऐसा कर सकता था

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

तो मान लीजिए कि मेरे पास सक्रिय लिंक डोम तत्व तक पहुंच है जो मैं कर सकता था

activeLink.classList.add('active')

और मैं सिर्फ सक्रिय वर्ग को html में पहले एंकर टैग में जोड़ सकता था

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

तो मैं इसे रिएक्ट में कैसे लागू करूं? कृपया कुछ सुझाव दें कि मुझे इस पर कैसे पहुंचना चाहिए या मैं क्या गलत कर रहा हूं।

1
ThePhilosopher 20 जिंदा 2021, 20:07
हम Header.tsx में / या /search आदि लाने के लिए window.location.pathname का उपयोग क्यों नहीं कर सकते हैं और फिर active class को Link को असाइन कर सकते हैं, जिसमें इस pathname के साथ मेल खाने वाला href?
 – 
Rohit Khanna
20 जिंदा 2021, 20:11
मुझे लगता है कि मैं तर्क को जटिल बना रहा हूं क्योंकि ऐसा लगता है कि इसका एक आसान समाधान होना चाहिए।
 – 
ThePhilosopher
20 जिंदा 2021, 20:12
मुझे लगता है कि मेरे द्वारा साझा किया गया समाधान समस्या का समाधान करना चाहिए, क्योंकि राउटर के मामले में, URL सत्य का एकमात्र स्रोत होना चाहिए।
 – 
Rohit Khanna
20 जिंदा 2021, 20:16
हाँ यह समझ में आता है। यह देखने की कोशिश कर रहा है कि क्या यह काम करता है।
 – 
ThePhilosopher
20 जिंदा 2021, 20:18
धन्यवाद दोस्त। पूरी तरह से काम किया! मैं गलत काम करने की कोशिश कर रहा था। जैसा कि आपने कहा, URL सत्य का एकमात्र स्रोत होना चाहिए।
 – 
ThePhilosopher
20 जिंदा 2021, 20:30

1 उत्तर

सबसे बढ़िया उत्तर

जैसा कि @Rohit द्वारा सुझाया गया है, मैंने सक्रिय लिंक स्थिति को वर्तमानपाथ को राज्य के रूप में संग्रहीत करने के लिए बदलने की कोशिश की और फिर बाद में 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>
  );
};

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

यह एक आकर्षण की तरह काम करता है।

0
ThePhilosopher 20 जिंदा 2021, 20:37
1
वास्तव में ऐसा लगता है कि आप सशर्त वर्ग नामों के साथ प्रतिक्रिया लड़ रहे हैं। आप इस डिज़ाइन को प्राप्त करने के लिए स्टाइल-घटकों और पासिंग प्रोप को देखना चाहेंगे।
 – 
serraosays
20 जिंदा 2021, 20:42