1

I'm making a web app that has a main header that is valid for all its pages and a second header that should be different for the Start page and only there. To be specific, the main header is just the app's title and the login/user profile button, and the second header shows some links. Now here's the problem: the Start page has a searchbox right in its middle, a bit like Google's initial page, while in the other pages this searchbox is moved to the second header, right beside the links that are already there.

The first solution I tried is to useParams to get the Start page's URL and do conditional rendering for the searchbox in the second header, like

params !== Start && <Searchbox />

But it didn't work and I couldn't figure out why. useParams is returning undefined, so I can't do much with it. Then I started thinking about other solutions like creating a div inside my router in App and adding the second header there, while Start stays outside, like so:

return (
         <>
            <Router>
                <Header />
                <Wrapper>
                    <Routes>
                        <Route exact path="/" element={<Start />} />
                    </Routes>
                    <div>
                        <SecondHeader>
                            <Sidebar />
                            <Searchbox />
                        </SecondHeader>
                        <Routes>
                            
                            [OTHER ROUTES]

                        </Routes>
                    </div>
                </Wrapper>
            </Router>
        </>
    );

This didn't work either and I believe this was expected, but I tried anyway. Other than that, as far as I know I can't have two routers, right? As in one in, say, App, and another one in Home, for instance, so that Home would both be Start's sibling and also a parent of the other pages. This isn't possible, right?

At this point I'm guessing conditional rendering is my best bet, but it isn't working. What do you people suggest I do?

EDIT: clarification and adding info.

  • Were you able to solve this yet? I'm curious why you need to use the useParams hook for URI parameters, if you already know what the path should be (assuming you would know what the Start page's URL is). Or maybe there is some more complexity missing in the question. – BioData41 Dec 29 '21 at 15:59
  • I believe you can have more than one Router, but why would you need to? From the details provided, I'm not sure why using my suggestion with the case-based rendering within (now ) wouldn't work. – BioData41 Dec 29 '21 at 16:13
  • I'm sorry for taking so long to reply. I got stuck elsewhere in the app and couldn't even get to this part. Now it's working, but I'm stuck in another part anyway, so I haven't been fiddling with the problem we're dealing here :'-) – Fred Barros Jan 10 '22 at 01:01
  • Anyway, my reasoning for useParams here is that they'd show the header that we are rendering the Start component and then it would trigger the conditional rendering not to show the Searchbox. I guess the way I phrased it up there is misleading. It's not that the Searchbox moves, I actually have two searchBoxes, one in the center of the Start component, and one rendered conditionally in the header. If we are in Start, the header doesn't show its searchBox, as there's one in the center. – Fred Barros Jan 10 '22 at 01:07

1 Answers1

0

When I've had to conditionally render one among several components based on the router address, I've done it like this, where the different Routes are within a Switch element. (https://v5.reactrouter.com/web/api/Switch)

import React from 'react';
import { Route, Link, Switch } from 'react-router-dom';

/*Here is a fragment I pulled out from within one of my render() functions,
  demonstrating the usage where only one of these Routes will be rendered,
  depending on the URL path:
*/
        <div id="contentdiv">
            <Switch>
                <Route exact path="/" component={Home} />

                <Route
                    path="/procdef"
                    render={(routeProps) => {
                        return (<ProcDefView />);
                    }}
                />

                <Route path="/execdata" component={ProcDataView} />

                <Route path="/eda" component={EDAView} />

            </Switch>
        </div>

This was probably with an older version of react-router, so not sure if something has changed.
Not sure why, but in this code I dug up, I used two different ways to pass in the components - one just passing the component as a prop to the element and the other passing a render function as a prop to the element, where that function returns the component.

Here is a prior SO thread on react-router Switch.

BioData41
  • 862
  • 9
  • 15
  • 1
    Yes, in the most recent version of React Router you use Routes instead of Switch and Route for each route. Anyway, I don't think this is where the problem lies. I have the impression that the problem is on useParams returning undefined. I forgot to state this in my original question and will update it now. – Fred Barros Dec 28 '21 at 02:05
  • Thanks for pointing that out, @FredBarros. Looks like the change from to happened between v5 and v6. – BioData41 Dec 28 '21 at 02:18