jaumeserr
jaumeserr

Reputation: 39

NavLink activeClassName selected on page load

Is it possible to push with history.push the url of the route on useEffect to maintain selected a Navlink on page load?

Navigation.tsx

export const Navigation = ({ userId }: { userId: Id }) => {
  const [ownEvents, setOwnEvents] = useState<EventsPerMonth[]>();
  const [attendedEvents, setAttendedEvents] = useState<EventsPerMonth[]>();
  const { url, path } = useRouteMatch();
  const { push } = useHistory()

  useEffect(() => {
    getCreatedEventsByUserId(userId).then(setOwnEvents);
    getAssistedEventsByUserId(userId).then(setAttendedEvents);
    push(`${url}/created-events`);
  }, [userId, push, url]);

  return (
    <>
      <StyledNavigation>
        <ul>
          <li>
            <StyledNavLink to={`${url}/created-events`} activeClassName="any">
              Eventos creados
            </StyledNavLink>
          </li>
          <li>
            <StyledNavLink to={`${url}/assisted-events`} activeClassName="any">
              Eventos asistidos
            </StyledNavLink>
          </li>
        </ul>
      </StyledNavigation>

      <Switch>
        <ProtectedRoute exact path={`${path}/created-events`}>
          {attendedEvents && <EventsList events={attendedEvents} />}
        </ProtectedRoute>
        <ProtectedRoute exact path={`${path}/assisted-events`}>
          {ownEvents && <EventsList events={ownEvents} />}
        </ProtectedRoute>
      </Switch>
    </>
  );
};

Is allowed?

useEffect(() => {
    getCreatedEventsByUserId(userId).then(setOwnEvents);
    getAssistedEventsByUserId(userId).then(setAttendedEvents);
    push(`${url}/created-events`);
  }, [userId, push, url]);

Is there any other way to do that?
Thanks!

Upvotes: 0

Views: 197

Answers (1)

Drew Reese
Drew Reese

Reputation: 203457

Issuing the navigation action from the useEffect hook is completely valid and allowed. Though, since it seems this Navigation component is really just calling some APIs to populate some local state and unconditionally navigating to one of the children routes, I'd probably suggest using a redirect (REPLACE) instead of a navigation (PUSH) action to help cut down on entries on the history stack.

const { replace } = useHistory();

useEffect(() => {
  getCreatedEventsByUserId(userId).then(setOwnEvents);
  getAssistedEventsByUserId(userId).then(setAttendedEvents);
  replace(`${url}/created-events`);
}, [userId, history, url]);

In fact, this redirect seems to only serve to get the user to the sub-route. You could render a Redirect instead, to redirect from the path to "{path}/created-events".

useEffect(() => {
  getCreatedEventsByUserId(userId).then(setOwnEvents);
  getAssistedEventsByUserId(userId).then(setAttendedEvents);
}, [userId, history, url]);

...

<Switch>
  <ProtectedRoute exact path={`${path}/created-events`}>
    {attendedEvents && <EventsList events={attendedEvents} />}
  </ProtectedRoute>
  <ProtectedRoute exact path={`${path}/assisted-events`}>
    {ownEvents && <EventsList events={ownEvents} />}
  </ProtectedRoute>
  <Redirect to={`${path}/created-events`} />
</Switch>

Upvotes: 1

Related Questions