3

I have created a page with some tabs on it. Tab codes are these:

const [ toggleState, setToggleState ] = useState(1);

const toggleTab = (index) => {
 setToggleState(index);
}

<div className="tab-title-Container">
 <li className= {toggleState === 1 ? "tab-name active-name" : "tab-name"} 
  onClick={() => toggleTab(1)}>Tab1</li>
 <li className= {toggleState === 2 ? "tab-name active-name" : "tab-name"} 
  onClick={() => toggleTab(2)}>Tab2</li>
</div>
<div className="tab-content-Container">
 <div className= {toggleState === 1 ? "tab-content active-content" : "tab-content"}>
  Tab1 Content</div>
 <div className= {toggleState === 2 ? "tab-content active-content" : "tab-content"}>
  Tab2 Content</div>
</div>

style:
.tab-content {display: none;}
.active-content {display: block;}

Now I want to create navbar links of each tab. When I click Tab2 navbar link, this page should open and Tab2 switch to active class (default active tab is Tab1). I am using react-router-dom": "^6.3.0".

I need to create routes like this "https://example.com/page=01#tab1", "https://example.com/page=01#tab2" for them.

1 Answers1

1

react-router-hash-link AFAIK hasn't been updated to be compatible with react-router-dom@6. That said, it doesn't appear you are using the hash for normal purposes. The URL hash value can be read from the location object and parsed to extract the numerical tab value. Use a useEffect hook to "listen" for changes to the hash to update the local toggleState state.

Example:

import { useEffect, useState } from "react";
import { useLocation } from "react-router-dom";

const Page = () => {
  const { hash } = useLocation();

  const [toggleState, setToggleState] = useState(1);

  useEffect(() => {
    setToggleState(Number(hash.slice(4))); // hash is "#tabX" so strip first 4 chars
  }, [hash]);

  const toggleTab = (index) => {
    setToggleState(index);
  };

  return (
    ...
  );
};

...

<Link to="/1#tab1">Page 1 tab 1</Link>
<Link to="/1#tab2">Page 1 tab 2</Link>
<Link to="/2#tab1">Page 2 tab 1</Link>
<Link to="/2#tab2">Page 2 tab 2</Link>

Edit how-to-create-react-tab-navbar-links-with-fragment-identifiers-hash-links

Like I said, this is a bit of an odd use of the URL hash. I think a query parameter would be an improved alternative.

Example:

import { useEffect, useState } from "react";
import { useSearchParams } from "react-router-dom";

const Page = () => {
  const [searchParams, setSearchParams] = useSearchParams();
  const { pageId } = useParams();

  const [toggleState, setToggleState] = useState(1);

  useEffect(() => {
    // access tab query parameter
    const tab = searchParams.get("tab");
    if (tab) {
      // synchronize local state
      setToggleState(Number(tab));
    } else {
      // redirect to correct tab
      searchParams.set("tab", 1);
      setSearchParams(searchParams, { replace: true });
    }
  }, [searchParams, setSearchParams]);

  const toggleTab = (index) => {
    setToggleState(index);
  };

  return (
    ...
  );
};

...

<Link to="/1?tab=1">Page 1 tab 1</Link>
<Link to="/1?tab=2">Page 1 tab 2</Link>
<Link to="/2?tab=1">Page 2 tab 1</Link>
<Link to="/2?tab=2">Page 2 tab 2</Link>

Edit how-to-create-react-tab-navbar-links-with-fragment-identifiers-hash-links (forked)

Drew Reese
  • 165,259
  • 14
  • 153
  • 181
  • 1
    I tried your second solution with query parameter and it worked perfectly as desired after some customization. – Kulbhushan Sharma Aug 03 '22 at 09:05
  • One issue noticed now: If I visit directly on Page1 using Page 1 all tabs show inactive. By default Tab1 should display on visiting to page. Please resolve this problem – Kulbhushan Sharma Aug 03 '22 at 09:47
  • @KulbhushanSharma Sure, it's trivial to manually redirect to a "default" tab. I've updated my answer and linked sandbox. Please do take a look when you can. – Drew Reese Aug 03 '22 at 17:14
  • Thanks for your valuable efforts. Now its working. Is there anyway to keep our url "www.myweb.com/1" instead of "www.myweb.com/1?tab=1" only when we use Page 1? – Kulbhushan Sharma Aug 04 '22 at 08:38
  • @KulbhushanSharma Absolutely there is. I think you can just call `setToggleState(1);` in the else branch instead of updating the query search params. – Drew Reese Aug 04 '22 at 08:41