'Uncaught TypeError: match is undefined leads to blank page
I'm currently doing a repo finder and I'm having an issue to make the program display the repo name
The main page looks like this
import {FaGithub, FaPlus, FaSpinner, FaBars, FaTrash} from 'react-icons/fa'
import {Container, Form, SubmitButton, List, DeleteButton} from './styles'
import {Link} from 'react-router-dom'
import api from '../../services/api'
export default function Main(){
const[newRepo, setNewRepo] = useState('')
const[repos, setRepos] = useState([])
const[loading, setLoading] = useState(false)
const [alert, setAlert] = useState(null)
useEffect(()=> {
const repoStorage = localStorage.getItem('repos')
if(repoStorage){
setRepos(JSON.parse(repoStorage))
}
}, [])
useEffect(()=> {
localStorage.setItem('repos', JSON.stringify(repos))
}, [repos])
const handleSubmit = useCallback((e)=>{
e.preventDefault()
async function submit(){
setLoading(true)
setAlert(null)
try{
if(newRepo === ""){
throw new Error("Repo must not be blank")
}
const res = await api.get(`repos/${newRepo}`)
const hasRepo = repos.find(repo => repo.name === newRepo)
if(hasRepo) {
throw new Error("This repo already exists")
}
const data = {
name: res.data.full_name,
}
setRepos([...repos, data])
setNewRepo('')
}
catch(err){
setAlert(true)
console.log(err)
}
finally{
setLoading(false)
}
}
submit()
}, [newRepo, repos])
function handleInputChange(e){
setNewRepo(e.target.value)
setAlert(null)
}
const handleDelete = useCallback((repo) => {
const find = repos.filter(r => r.name !== repo)
setRepos(find)
}, [repos])
return(
<Container>
<FaGithub size={25}/>
<h1>My Repos</h1>
<Form onSubmit={handleSubmit} error={alert}>
<input type="text"
placeholder='Add repos'
value={newRepo}
onChange={handleInputChange}/>
<SubmitButton loading={loading ? 1 : 0}>
{
loading ? (
<FaSpinner color= "#FFF" size={14}/>
):(
<FaPlus color="#FFF" size={14}/>
)
}
</SubmitButton>
</Form>
<List>
{repos.map(repo=> (
<li key={repo.name}>
<DeleteButton onClick={()=> handleDelete(repo.name)}>
<FaTrash size={14}/>
</DeleteButton>
<span>{repo.name}</span>
<Link to={`repo/${encodeURIComponent(repo.name)}`}>
<FaBars size={20}/>
</Link>
</li>
))}
</List>
</Container>
)
}
User will be able to either add repos, delete them or see their details. Clicking the button to see details will redirect to the following page
import React from 'react'
export default function Repos({match}){
return(
<h1 style={{color:'#FFF'}}>
Repos
{decodeURIComponent(match.params.repo)}
</h1>
)
}
However, when I check the console, it gives the following error: Uncaught TypeError: match is undefined
What is missing or written wrong ?
The route code
import React from 'react'
import {BrowserRouter, Routes, Route} from 'react-router-dom'
import Main from './pages/main'
import Repo from './repos'
export default function RouteManager(){
return(
<BrowserRouter>
<Routes>
<Route exact path="/" element ={<Main/>}/>
<Route exact path="/repo/:repo" element ={<Repo/>}/>
</Routes>
</BrowserRouter>
)
}
index page
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
App.js code
import React from 'react'
import RouteManager from './routes'
import GlobalStyle from './styles/global'
function App() {
return (
<>
<GlobalStyle/>
<RouteManager/>
</>
);
}
export default App;
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>
Router-Dom version used on this code is v6
Solution 1:[1]
Found the issue.
Basically, I had to pass the parameter like this:
import React from "react";
import {useParams} from 'react-router-dom'
export default function Repos(){
let { repo } = useParams()
return(
<h1 style={{color: "#FFF"}}>
{repo}
</h1>
)
}
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 | Arnav Thorat |