How to set a NavLink to active conditionally on dynamic links

In my menu, I have a navigation link- My Profile. When the user clicks My Profile react redirects to their profile. Then the nav link is set to active as expected, likewise, the isActive style is applied.

        <NavLink className="nav-link" to="/my_profile" activeStyle={isActive}>
          My Profile
        </NavLink>

A user can navigate to users’ profiles by navigating to www.sitename.com/***username*** (like Twitter or Instagram).

          <Route path="/:profile_name">
            <Profile />
          </Route>

When a user is logged in and navigates to their own profile through this dynamic route, I want the nav link for My Profile to be set to active. But I can only figure out how to set My Profile to active when My Profile is clicked on, not when the user navigates to their own profile through the address bar.

How can I set the NavLink for My Profile to active when a user navigates to their dynamic profile route through the address bar?

Example

In my code example, I have the currentUser hard coded in as dash123, so when we navigate to http://somedomain.com/dash123 the Profile component recognizes /dash123 is the current user’s profile and sets the state authorized to true. When authorized is true, Profile renders to display “Edit your profile”. Can I also make it so when authorized is true, the NavLink for My Profile is set to active?

CodeSandbox

Code:

import React, { useState, useEffect } from "react";
import {
  NavLink,
  BrowserRouter as Router,
  Route,
  Switch,
  useParams
} from "react-router-dom";

function Nav() {
  const isActive = {
    fontWeight: "bold",
    backgroundColor: "lightgrey"
  };

  return (
    <ul className="navbar-nav mr-auto">
      <li className="nav-item">
        <NavLink className="nav-link" to="/Shop" activeStyle={isActive}>
          Shop
        </NavLink>
      </li>
      <li className="nav-item">
        <NavLink className="nav-link" to="/my_profile" activeStyle={isActive}>
          My Profile
        </NavLink>
      </li>
    </ul>
  );
}
function Shop(props) {
  return (
    <div>
      Lots of items to buy
      <br /> Shoes $4.99
      <br /> Carrots $9.99
      <br /> Teslas $800,000
    </div>
  );
}
function Profile(props) {
  let { profile_name } = useParams();
  const [profile, setProfile] = useState();
  const [authorized, setAuthorized] = useState(null);

  // fake calls to database
  const currentUser = () => {
    return { name: "Dashie" };
  };
  const userInfo = (username) => {
    const db = [
      { username: "dash123", name: "Dashie" },
      { username: "bob123", name: "Bob" }
    ];
    return db.find((userDoc) => userDoc.username === username);
  };

  useEffect(() => {
    if (props.profile === "currentUser") {
      setProfile(currentUser());
    } else {
      setProfile(userInfo(profile_name));
    }
  }, [profile_name, props.profile]);
  useEffect(() => {
    if (profile && profile.name === currentUser().name) {
      setAuthorized(true);
    }
  }, [profile]);

  return (
    <div>
      Profile:
      <br />
      {profile && <>Name: {profile.name}</>}
      <br />
      {authorized && profile && <>Edit your profile, {profile.name}</>}
    </div>
  );
}

export default function App() {
  return (
    <div className="App">
      <Router>
        <Nav />
        <Switch>
          <Route path="/shop">
            <Shop />
          </Route>
          <Route path="/my_profile">
            <Profile profile={"currentUser"} />
          </Route>
          <Route path="/:profile_name">
            <Profile />
          </Route>
        </Switch>
      </Router>
      <h2>Problem</h2>
      <p>
        If you click on <b>Shop</b>, as expected the <b>Shop</b> nav link will
        be highlighted.
        <br />
        <br /> Likewise, the <b>My Profile</b> nav link will be highlighted when
        we click on it and navigate to the user's profile.
        <br />
        <br /> But, we also want to have <b>My Profile</b> highlighted when we
        navigate to,{" "}
        <i>
          "https://whateverdomainyouron/<b>dash123</b>"
        </i>{" "}
        since this takes us to the current user's profile.
      </p>
    </div>
  );
}

Answer

I took Drew Reese’s suggestions and expanded on them to fit my needs.

I made it so the My Profile link is active if isProfileRoute and currentUsersProfile is met.

        <NavLink
          isActive={() => isProfileRoute && currentUsersProfile}
          className="nav-link"
          to="/my_profile"
          activeStyle={isActive}
        >

currentUsersProfile is on the AuthContext.

const AuthContext = createContext({
  authorized: false,
  profile: null,
  currentUsersProfile: null,
  setAuthorized: () => {},
  setProfile: () => {},
  setCurrentUsersProfile: () => {},
});

The currentUsersProfile is set in Profile to true when the current profile belongs to the current logged in user.:

  useEffect(() => {
    if (profile?.name === currentUser().name) {
      setAuthorized(true);
      setCurrentUsersProfile(true);
    } else {
      setCurrentUsersProfile(false);
    }
  }, [profile]);

I create an array of all the routes:

const Routes = (
    <Switch>
    <Route path="/shop">
      <Shop />
    </Route>
    <Route path={"/pro"}>
      <Profile />
    </Route>
    <Route path={["/:profile_name", "/my_profile"]}>
      <Profile />
    </Route>
  </Switch>
);
const array = Routes.props.children.map((child) => child.props.path);
// outputs: ['/shop', '/pro', ["/:profile_name", "/my_profile"]]

In Nav I use this array to check to see if the current route the user is on is a the profile route (ex: ‘/dash123’, ‘/somename’, or the fixed route ‘/my_profile’) using useMatchRoute

function Nav() {
  const { currentUsersProfile } = useContext(AuthContext);
  const allNonProfileRoutes = array.slice(0, -1);
  let nonProfileRoute = useRouteMatch([...allNonProfileRoutes, { path: "/" }]);

  const isProfileRoute = !nonProfileRoute.isExact;

codesandbox