'Not able to link a component in react js

I wrote a code to fetch a list of contacts, after clicking on the view detail button on the contact card, it should open a new page showing the contact details

But in my code when I click on the view details button a new page is opening with the same existing cards view. I am not sure why contactdetails component is not showing in new page.

Same view when I click on view details button

app.js

import './App.css';
import React from 'react';
import ContactsList from './components/ContactList.js';        
        
function App() {
  return (
    <React.Fragment>
      <ContactsList></ContactsList>
    </React.Fragment>
  );
}
        
export default App;

ContactsList.js

import React, { Fragment } from 'react';
import Contact from './Contact';    

export default function ContactsList() {
  var images = [],
  index = 0;
  images[0] = 'https://www.computerhope.com/banners/banner.gif';
  images[1] = 'https://www.computerhope.com/banners/banner2.gif';
  images[2] = 'https://www.computerhope.com/banners/banner3.gif';
  index = Math.floor(Math.random() * images.length);
    
  const[contacts, setContacts] = React.useState([]);
    
  React.useEffect(function effectFunction(){
    fetch('https://jsonplaceholder.typicode.com/users')
    .then(response => response.json())
    .then(data => {
      console.log((data));
      setContacts(data);
    });
  },[]);
  return(   
    {contacts.map(item => (
      <Contact
          key={item.id}
          name={item.name}
          email={item.email}
          image = {images[Math.floor(Math.random() * images.length)]}
        />
      ))
    };  
  );        
}

Contact.js

import React, { Fragment } from 'react';
import { Card , Button,} from 'react-bootstrap';
import ContactDetail  from './ContactDetail';
import {
    BrowserRouter as Router,
    Switch,
    Route,
    Link,
    BrowserRouter
} from "react-router-dom";
     
export default function Contact({key, name, email, image}) {
    return (
        <Card key = {key}>
            <Card.Img src = {image} alt = "Loading"></Card.Img>
            <Card.Body>
                <Card.Title> {name} </Card.Title>
                <Card.Text>Contact: {email} </Card.Text>
                <BrowserRouter>
                <Link to = {{pathname: '/ContactDetail', query:{cname :{name}, email : {email} , image: {image}}  }} className="btn btn-primary" target="_blank">
                    View Details
                </Link>
                <Route
                    path="/ContactDetail"
                    component={ContactDetail} 
                />
                </BrowserRouter>
            </Card.Body>
        </Card>
    );
}

ContactDetail.js

import React, { Fragment } from 'react';
import { Image } from 'react-bootstrap';

export default function ContactDetail({cname, email, image}) {
    return(
        <Fragment>
            <Image src ={image} rounded></Image>
            <h1> {cname} </h1>
        </Fragment>
    );
}


Solution 1:[1]

Here is the working code. Hope it will help you, you missed exact word in router which matches exact route first.

app.js

import React, { useState } from "react";
import { Route, BrowserRouter, Switch } from "react-router-dom";
import ContactsList from "./ContactsList";
import ContactDetail from "./ContactDetail";

export default function App() {
  const [contacts, setContacts] = useState({
    cname: "John Doe",
    email: "[email protected]",
    image: "https://www.computerhope.com/banners/banner.gif"
  });

  return (
    <BrowserRouter>
      <React.StrictMode>
        <Switch>
          <Route exact path="/">
            <ContactsList />
          </Route>
          <Route path="/ContactDetail">
            <ContactDetail {...contacts} />
          </Route>
        </Switch>
      </React.StrictMode>
    </BrowserRouter>
  );
}

ContactDetail.js

import React, { Fragment } from "react";
import { Image } from "react-bootstrap";

export default function ContactDetail({ cname, email, image }) {
  return (
    <Fragment>
      <Image src={image} rounded></Image>
      <h1> {cname} </h1>
    </Fragment>
  );
}

ContactsList.js

import React, { useEffect, useState } from "react";
import Contact from "./Contact";

export default function ContactsList() {
  var images = [],
    index = 0;
  images[0] = "https://www.computerhope.com/banners/banner.gif";
  images[1] = "https://www.computerhope.com/banners/banner2.gif";
  images[2] = "https://www.computerhope.com/banners/banner3.gif";
  index = Math.floor(Math.random() * images.length);

  const [contacts, setContacts] = useState([]);
  useEffect(function effectFunction() {
    fetch("https://jsonplaceholder.typicode.com/users")
      .then((response) => response.json())
      .then((data) => {
        console.log(data);
        setContacts(data);
      });
  }, []);
  return contacts.map((user) => (
    <Contact
      key={user.id}
      name={user.name}
      email={user.email}
      image={images[Math.floor(Math.random() * images.length)]}
    />
  ));
}

Contacts.js

import React from "react";
import { Card } from "react-bootstrap";
// import ContactDetail from "./ContactDetail";
import { Link } from "react-router-dom";

export default function Contact({ key, name, email, image }) {

  return (
    <Card key={key}>
      <Card.Img src={image} alt="Loading"></Card.Img>
      <Card.Body>
        <Card.Title> {name} </Card.Title>
        <Card.Text>Contact: {email} </Card.Text>
        <Link
          to={{
            pathname: "/ContactDetail",
            query: { cname: { name }, email: { email }, image: { image } }
          }}
          className="btn btn-primary"
        >
          View Details
        </Link>
        {/* <Route path="/ContactDetail" component={ContactDetail} /> */}
      </Card.Body>
    </Card>
  );
}

https://codesandbox.io/s/hardcore-glade-8h7jc

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Salman Bukhari