I'm basically trying to show some data in one of my components. The data is passed from my main page but I can't get it to work using useLocation
.
I'm getting the data from my firebase db.
My main page is a job board and I want users to be able to click on the job card and go to a new page with all the details of that job.
I see on the console that I get the data but I can't seem to display it in my component/page. I get undefined when doing console.log
See below for more details:
Jobs.js
import { Link, useNavigate } from "react-router-dom";
export default () => {
const navigate = useNavigate();
const [jobs, setJobs] = useState([]);
return (
<div>
{jobs.map(job => {
return (
<div key={job.id}>
//My attempt using Link
<Link
to={`/view-contact-details/${job.id}`}
state={{jobs}}
>
<button>View</button>
</Link>
//My attempt using useNavigate
<button onClick={() => {
navigate(`/view-contact-details/${job.id}`, { state:{ jobs } });
}}
>
Go To Job details
</button>
</div>
);
})}
</div>
);
};
App.js
import React from "react";
import Jobs from "./pages/jobs"
import Form from "./pages/form"
import { Routes, Route } from "react-router-dom"
import ViewUserDetails from "./components/Job/ViewJobDetails";
export default () => {
return (
<div className="App">
<Routes>
<Route exact path='/' element={<Jobs/>} />
<Route exact path='/form' element={<Form/>} />
<Route
exact
path="/view-contact-details/:id"
element={<ViewJobDetails/>}
/>
</Routes>
</div>
);
};
ViewJobDetails.js
import React from "react";
import { useLocation, } from "react-router-dom";
export default (props) => {
const location = useLocation();
console.log(location); // shows jobs on the page yet can't display
//I also tried
//const {state} = location
//{state.job.description}
return (
<>
<div>
<div>
<div>
<strong>Description:</strong>
{location.state.job.description} //doesn't work
{location.job.description} //doesn't work
{location.state.description} //doesn't work
</div>
<div>
<strong>Title:</strong>
</div>
</div>
</div>
</>
);
};
CodePudding user response:
The passed state jobs
is an array. In the component you are accessing a job
property that is undefined.
Access the correct state.jobs
array and map it to JSX.
Example:
export default (props) => {
const { state } = useLocation();
const { jobs } = state || []; // <-- access state.jobs
return (
<div>
{jobs.map(job => ( // <-- map jobs array
<React.Fragment key={job.id}>
<div>
<strong>Description:</strong>
{job.description}
</div>
<div>
<strong>Title:</strong>
{job.title}
</div>
</React.Fragment>
))}
</div>
);
};
If on the offhand chance you meant to pass only a single job, i.e. the current job from Jobs
, then instead of passing the entire array, pass only the currently iterated job
object.
export default () => {
const navigate = useNavigate();
const [jobs, setJobs] = useState([]);
return (
<div>
{jobs.map(job => {
return (
<div key={job.id}>
//My attempt using Link
<Link
to={`/view-contact-details/${job.id}`}
state={{ job }} // <-- pass current job
>
<button>View</button>
</Link>
//My attempt using useNavigate
<button
onClick={() => {
navigate(
`/view-contact-details/${job.id}`,
{ state:{ job } } // <-- pass current job
);
}}
>
Go To Job details
</button>
</div>
);
})}
</div>
);
};
Then in the JobDetals
component access location.state.job
.
export default (props) => {
const { state } = useLocation();
const { job } = state || {};
return (
<>
<div>
<div>
<div>
<strong>Description:</strong>
{job.description}
</div>
<div>
<strong>Title:</strong>
{job.title}
</div>
</div>
</div>
</>
);
};