LiquidDeath
LiquidDeath

Reputation: 1828

How to Show two components for a url in react js

below is my app.js code which will show the components based on the url. when user goes to /home, i need to perform some cookie operations. which i'm able to do. Since home component is required for more than one url, every url(/new,/dashboard) performs the cookie operation. Is it normal behavior ?

Below is my code, please let me know if this is react way to write it or not. I'm new to react js.

function App() {
  return (
    <div className="App">
      <Router>
        <Navbar />
        
        <Switch>
          <Route path="/" exact />
        </Switch>
        
        <Route path="/Home">
           <Home />
           <About />
        </Route>
       
        <Route path="/New">
          <Home />
          <New />
        </Route>
        
        <Route path="/Dashboard">
          <Home />
          <Dashboard />
        </Route>
        
        <Route path="/Run/:testid/">
          <Run>
        </Route>
        
      </Router>
    </div>
  );
}

export default App;

below is my home component :

import { React, useEffect } from "react";
import { Button } from "./Button";
import { Link } from "react-router-dom";
import "./Navbar.css";
import "./Home.css";
import useQuery from "../hooks/useQuery";

function Home(props) {

  const q = useQuery();
  console.log(q.get("token"));
  
  //save the token in cookie if url is /home, but since this home component is render for other urls like /new, /dashboard, it gets executed there as well. 

  return (
    <main id="maincontent">
      <div className="dashboard-btns">
        <Link to="/dashboard" className="btn-mobile">
          <Button id="dashboard" buttonStyle="btn--secondary">
            Dashboard
          </Button>
        </Link>
        <Link to="/new" className="btn-mobile">
          <Button id="new" buttonStyle="btn--secondary">
            New
          </Button>
        </Link>
        <hr className="hr-line" />
      </div>
    </main>
  );
}

export default Home;

In the < Home > component save the token in cookie only if url is /home, but since this home component is rendered for other urls like /new, /dashboard, it gets executed there as well. How do i make it get executed only for /home url

Upvotes: 1

Views: 529

Answers (3)

Drew Reese
Drew Reese

Reputation: 203267

If you want the Home component to render on several routes then you can refactor your routes as such, and specify an array of paths for the route rendering Home. The Router component inclusively matches and render routes, in other words, it renders all matching routes.

function App() {
  return (
    <div className="App">
      <Router>
        <Navbar />

        <Switch>
          <Route path="/" exact /> // what is this for?
        </Switch>

        <Route path={["/Home", "/New", "/Dashboard"]}>
           <Home />
        </Route>
        <Route path="/Home">
           <About />
        </Route>
        <Route path="/New">
          <New />
        </Route>
        <Route path="/Dashboard">
          <Dashboard />
        </Route>
        
        <Route path="/Run/:testid/">
          <Run>
        </Route>
      </Router>
    </div>
  );
}

Update

I'm doing some cookie storing and fetching operation in component. But that should happen only on "/home" url and shouldn't happen on "/new", "/dashboard" url. How do I do that?

You can check the current path match and issue a side-effect to do the cookie logic on only the "/home" path.

useRouteMatch

The useRouteMatch hook attempts to match the current URL in the same way that a <Route> would. It’s mostly useful for getting access to the match data without actually rendering a <Route>.

match will be null if path isn't a match, otherwise it will return a match object.

import { React, useEffect } from "react";
...
import { Link, useRouteMatch } from "react-router-dom";
...
import useQuery from "../hooks/useQuery";

function Home(props) {
  const q = useQuery();
  console.log(q.get("token"));
  
  const homeMatch = useRouteMatch("/home");

  useEffect(() => {
    if (homeMatch) {
      //save the token in cookie if url is /home and token defined
      const token = q.get("token")
    }
  }, [homeMatch, q]);

  return (
    ...
  );
}

Upvotes: 1

pshrimal000
pshrimal000

Reputation: 97

First thing is you can use "exact" to prevent that behaviour, Second you should not use two components inside route, what you can do is you can import Home inside New and Dashboard and use it there.

Upvotes: 0

Related Questions