Reputation: 23
I am creating a simple portfolio application for which I require a separate screen for each project from a list of projects. In doing so when I try to get the Id of that project from the URL using match.params.id
, it gives a TypeError : Cannot read property 'params' of undefined
.
My code ProductScreenById:
import db from '../firebase'
export const ProjectScreenById = ({ match }) => {
const pid = match.params.id
return (
<div>
hello world
</div>
)
}
My ProjectListScreen:
import db from '../firebase'
import { Row, Col, Spinner } from 'react-bootstrap'
import { Project } from '../components/Project'
export const ProjectScreen = () => {
const [projects, setProjects] = useState([])
useEffect(() =>{
db.collection('projects').orderBy('index','asc').onSnapshot(snapShot => {
setProjects(snapShot.docs.map(doc => ({id:doc.id, project:doc.data()})))
})
},[])
const windowWidth = () => {
const { innerWidth:width, innerHeight:height } = window;
return { width, height }
}
return (<>
{projects.length===0 ?
<div className='mt-5 pt-5'>
<Spinner animation='border' style={{ width:100, height:100 }}/>
</div>
: (
<Row style={{ overflowX: 'hidden', width:'100%' }} className='pl-5 pt-5'>
{projects.map(project => (
<Col key={project.project.index} className='mr-2 mb-5'>
<Project
description={project.project.description.split('.')}
title={project.project.title}
features={project.project.features.split('.')}
git={project.project.git}
link={project.project.link}
index={project.project.index}
id={project.id}
stack={project.project.stack}
/>
</Col>
))}
</Row>
)}
</>
)
}
My Project Component:
import React from 'react'
import { Card, Image } from 'react-bootstrap'
import { Link } from 'react-router-dom'
export const Project = ({ description, features, git, index, link, stack, title, id }) => {
const images = [
'./images/ecom/display.png',
'./images/ytclone/display.png',
'./images/calculator/display.png',
'./images/todo/display.png',
'./images/expense/display.png',
' ./images/techS/display.png',
'./images/tictactoe/display.png',
'./images/canvas/display.png',
'./images/linked/display.png'
]
return (
<Card className='py-3 px-5' style={{ height:'100%'}} sm={12}>
<Image src={images[parseInt(index)]} style={{ width:'100%', border:'0.5px ridge rgb(219,219,219)' }} className='image' />
<b>{title}</b>
<div style={{ textAlign:'left' }} className='mb-2' >
<b>Description:</b>
{description.map(d=>(
<li key={description.indexOf(d)}>{d}</li>
))}</div>
<div style={{ textAlign:'left' }} className='mb-2' id='features'>
<b>Features:</b>
{features.map(f=>(
<li key={features.indexOf(f)}>{f}</li>
))}
</div>
<div style={{ textAlign:'left' }} className='mb-2' id='stack'>
<b>Tech Stack:</b>
{stack.map(s=>(
<li key={stack.indexOf(s)}>{s}</li>
))}
</div>
<div style={{ textAlign:'left' }} className='mb-2' id='git' >
<b>Git Repo: </b>
<a href={git.slice(0,5)==='https' ? git : '/projects'} target='_blank'>{git}</a>
</div>
<div style={{ textAlign:'left' }} className='mb-2' id='link' >
<b>Project link: </b>
<a href={link==='Upcoming' || link==='N/A' ? '/projects' : link}>{link}</a>
</div>
<Link to={`/projects/${id}`} className='view'><b>View Project & Project Details</b></Link>
</Card>
)
}
App.js:
import './App.css';
import { ContactScreen } from './screens/ContactScreen'
import { ProjectScreen } from './screens/ProjectScreen'
import { Header } from './components/Header'
import { Footer } from './components/Footer'
import { ProjectScreenById } from './screens/ProjectScreenById'
import { BrowserRouter as Router, Route } from 'react-router-dom'
function App() {
return (
<div className="App">
<Header/>
<Router>
<Route path="/contact" component={ContactScreen} exact/>
<Route path="/projects" component={ProjectScreen} exact />
<Route path="/projects/:id" component={ProjectScreenById} exact/>
</Router>
<Footer/>
</div>
);
}
export default App;
Upvotes: 0
Views: 419
Reputation: 388
This answer should help you out, but until then, here's a quick hack for it with useLocation
:
const location = useLocation()
const ID = location.pathname.split("/projects/")[1]
Upvotes: 1