Kamran Ali
Kamran Ali

Reputation: 61

How to pass Data in Route State React js

I am trying to pass data in Route State from link. I want to open Contact Detail Page. My code is

import React from 'react'
import Me from "../images/blank-profile-picture-973460__340.webp"
import {Link,useNavigate} from "react-router-dom"
const Contactlists = (props) => {
const Contact =props.Contact;;
const Deleteitem=(ID)=>{
props.deletehandler(ID);
}

  return (
    <div className='ui called list' style={{marginTop:"50px"}}> 
  <h2>Contact List</h2>
<Link to="/add">
<button className='ui button blue right'>Add Contact</button>
</Link>
 {
  Contact.map((curlElem)=>{
return(
  <div className='item' key={curlElem.id}>
  <img src={Me} className='ui avatar image' alt="user"/>
<div className='ui content'>
<Link to={`/contactdetail/${curlElem.id}`} state={{ Contact:Contact }}>

<div className='header'>{curlElem.name}</div>
<div>{curlElem.email}</div>
{/* <button>{curlElem.name}</button> */}
</Link>
    </div>
<span><i className='trash alternate outline icon' style={{color:"red",marginLeft:"7px"}}
onClick={()=>Deleteitem(curlElem.id)}
key={curlElem.id}
></i></span>
        </div>
);
  })
 }
 
    </div>
  )
}

export default Contactlists

here is my route

<Route path="/contactdetail/:id" element={<ContactDetail  />}/>

here is the component where i am accessing it but it show blank page i tried many different methods but insane

import React from 'react'
import me from "../images/me3.jpg"
import {useLocation} from "react-router-dom"
const ContactDetail = () => {
  const location=useLocation();
  const Contact=location.state?.Contact;
  console.log(Contact)
  // console.log(props.detailcontact);
  // const{id,name,email}=props.detailcontact;
  return (
   <div className='main'>
    <div className='ui card centered'>
      <div className='image'>
<img src={me} alt="me"/>
      </div>
<div className='content'>
<div className='header'>Name:{Contact.name}</div>
<div className='discription'>Email:{Contact.email}</div>
</div>
    </div>

   </div>
  )
}

export default ContactDetail

here is data i am receiving in Console Log

0: {name: 'kamran', email: 'kamranalizx491gmail.com', id: '4a2f1073-cf0b-47c7-bca4-b4915c4933a5'}
1: {name: 'Techistic Kami', email: '[email protected]', id: 'b597cb0a-3355-45ab-9ac7-1c05c0b8cdb0'}
2: {id: '54b94038-8c3c-4ef7-b330-3fd2dcfd081d', name: 'kam', email: '[email protected]'}
3: {id: '2658f40d-1f9d-42d7-b766-ab00afd47a91', name: 'Kamran Ali', email: 'kamranalizx491gmail.com'}
4: {id: '7d1f4a6c-0e88-4d90-9f23-5bd77c4f3fe4', name: 'Kamran Ali', email: '[email protected]'}
5: {id: '949f3dfc-7623-48d8-8ebc-2d3e39af6eaa', name: 'kamran', email: '[email protected]'}
6: {name: 'Kamran Ali', email: '[email protected]', id: '2abbc0d6-bd40-49be-903f-3135aaa8d4a5'}
7: {name: 'Kamran Ali', email: '[email protected]', id: 'ae8b4841-7418-4ea8-a20f-0d300a5eb850'}
8: {name: 'Kamran Ali', email: '[email protected]', id: 'e4fe382f-7e35-49eb-9c48-f5dd667fd3bf'}
9: {name: 'Kamran Ali', email: '[email protected]', id: '65a2f9f7-9031-4b52-9def-2b65f501ea75'}
10: {id: '61855c5a-0821-49e5-966b-509883b0a6db', name: 'Kamran Ali', email: '[email protected]'}
11: {id: '282a1f6b-d0c8-4fde-bb60-0abd3cbd5ef6', name: 'Kamran Ali', email: '[email protected]'}
12: {id: '80823775-e4bc-4d33-bc59-4270ba423edd', name: 'Kamran Ali', email: '[email protected]'}
13: {id: '5b66e91c-0c93-48df-820f-29a6493e3407', name: 'zain', email: '[email protected]'}
length: 14

Now I have edit the code please and suggest me the best solution as I am new to react js and following tutorial from youtube but I am facing many problems as I do the same like instructor

Upvotes: 1

Views: 2050

Answers (2)

Drew Reese
Drew Reese

Reputation: 202618

Issue

The issue here is that you are sending all the data in the route state. In other words, the code is passing the entire array, the id, name, and email properties are undefined in this array.

A second issue is that that the ContactDetail doesn't handle rendering when the location.state.Contact is undefined. It assumes there's a defined object to destructure properties from.

Solution

Either filter the array prior to sending it, or filter the passed state in the receiving component. In this case you likely meant to send the specific element value that is being mapped.

Example:

{Contact.map((curlElem) => {
  return(
    <div className='item' key={curlElem.id}>
      <img src={Me} className='ui avatar image' alt="user" />
      <div className='ui content'>
        <Link
          to={`/contactdetail/${curlElem.id}`}
          state={{ Contact: curlElem }} // <-- pass curlElem here!!
        >
          <div className='header'>{curlElem.name}</div>
          <div>{curlElem.email}</div>
        </Link>
        ...

Update ContactDetail to handle possibly undefined state.

const ContactDetail = () => {
  const { state } = useLocation();
  const { Contact = {} } = state || {}; // <-- provide fallback value

  console.log(Contact);

  return (
    <div className='main'>
      <div className='ui card centered'>
        <div className='image'>
          <img src={me} alt="me"/>
        </div>
        <div className='content'>
          <div className='header'>Name:{Contact.name}</div>
          <div className='description'>Email:{Contact.email}</div>
        </div>
      </div>
    </div>
  );
};

Upvotes: 0

ivanatias
ivanatias

Reputation: 4033

React router's Link component takes a state prop where you can pass data to the component that should be rendered for your path, example:

<Link to="/your-path" state={{ data: data }}>
   Some text
</Link>

Then in your component, you can access this data using useLocation hook:

const location = useLocation();
const data = location.state?.data;

To be more specific with your case, you can pass the data in your Link like so:

<Link to={`/contactdetail/${curlElem.id}`} state={{ name: curlElem.name, email: curlElem.email, id: curlElem.id }}>
   Some text
</Link>

That way you can access the specific data you need in your component:

const location = useLocation();
const { name, email, id } = location.state;

Upvotes: 1

Related Questions