skip to Main Content

I need to change the value in the header depending on which route I am in. The only dubious idea comes to place a separate header for each router, but it seems like it won’t be quite right.

ui with header values

<Header 
  loggedIn={loggedIn}
  email={email}
  onLoggin={setLoggedIn}
/>

<Routes>
  <Route
    path="/"
    element={loggedIn
      ? <Navigate to="/main" replace />
      : <Navigate to="/sign-in" replace />
    }
  />
  <Route path="/main" element={<ProtectedRoute element={Main}/>} />
  <Route path="/sign-up" element={<Register />} />
  <Route path="/sign-in" element={<Login />} />
</Routes>

I stopped at the fact that I was able to add and hide a login depending on the login to the account.

2

Answers


  1. You can do it by taking the pathname from the URL, Like if pathname is login then show login in header, if its register show register or if user is logged in show user email. Here is a snippet of code. t solves your problem.

    let obj = {
      'login': 'login',
      'registration': 'registration',
      'loggedIn': `${email}`
    }
    
    const location = useLocation();
    const [headerTitle, setHeaderTItle] = useState()
    let path = location.pathname;
    
    useEffect(() => {
      if (obj[path] === path) {
        setHeaderTItle(obj[path]) // use this header title in you header
      }
    }, [path])
    

    Here first use useLocation hook to get the pathname, then match the pathname with the paths defined in obj, Inside useEffect you can add another condition like if no path matched show user email or any dummy data.

    Login or Signup to reply.
  2. For patterns like this I suggest creating a header layout component that keeps the value you want to render in state and exposes an updater function that routed components can update when their route is matched.

    Example:

    import {
      Outlet,
      useOutletContext
    } from "react-router-dom";
    
    const HeaderLayout = () => {
      const [title, setTitle] = useState("");
    
      return <Outlet context={{ title, setTitle }} />;
    };
    
    const HeaderWrapper = ({ children, title }) => {
      const { setTitle } = useOutletContext();
    
      useEffect(() => {
        setTitle(title);
      }, [setTitle, title]);
    
      return (
        <>
          <Header />
          {children}
        </>
      );
    };
    

    The Header component is updated to read the value from the provided outlet context provider.

    const Header = ({ .... }) => {
      const { title } = useOutletContext();
    
      return (
        ...
        <h1>Header - {title}</h1>
        ...
      );
    };
    

    Routes

    <Routes>
      <Route element={<HeaderLayout />}>
        <Route
          path="/"
          element={<Navigate to={loggedIn ? "/main" : "/sign-in" replace />}
        />
        <Route element={<ProtectedRoute />}>
          <Route
            path="/main"
            element={
              <HeaderWrapper title="[email protected]">
                <Main} />
              </HeaderWrapper>
            }
          />
        </Route>
        <Route
          path="/sign-up"
          element={
            <HeaderWrapper title="Register">
              <Register />
            </HeaderWrapper>
          }
        />
        <Route
          path="/sign-in"
          element={
            <HeaderWrapper title="Login">
              <Login />
            </HeaderWrapper>
          }
        />
      </Route>
    </Routes>
    

    The HeaderWrapper wrapper component is optional since the routed components could just as easily use the useOutletContext hook themselves and call setTitle, but this couples the UI components to an implementation detail they don’t necessarily need to be concerned with.

    If this is the route your prefer then I’d suggest a custom hook.

    const useHeaderTitle = title => {
      const { setTitle } = useOutletContext();
    
      useEffect(() => {
        setTitle(title);
      }, [setTitle, title]);
    };
    

    Then the routed components just call the hook and pass their header title value.

    const Login = () => {
      useHeaderTitle("Login");
    
      ...
    };
    

    Edit change-values-depending-on-routes

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search