Reputation: 637
I am trying to use an array defined as a const in React, and pass this array in my App function. However, when I try to use it, I am getting a "TypeError: products is undefined" (in regards to <li> {products[0].id}</li>
).
Any help would be much appreciated. I have attached my App.js file, and stripped the application down to it's bare to attempt to single out the issue.
The link to the complete project can be found here: https://github.com/coopertim13/ProblematicReact
import React, { useState } from 'react';
import ReactDOM from 'react-dom'
const products = [
{id: 'P1000', name:'UGG', category: 'Cool'}
]
const App = (props) => {
const {products} = props
return (
<div>
<ul>
<li> {products[0].id}</li>
</ul>
</div>
)
}
ReactDOM.render(
<React.StrictMode>
<App products = {products}/>
</React.StrictMode>,
document.getElementById('root')
);
export default App;
Upvotes: 0
Views: 122
Reputation: 13775
The error tells you what you need to know. Your prop on App
is called units, but you're trying to destructure products
from it, which is undefined
.
Change const {products} = props
to const {units} = props
and then change <li> {products[0].id}</li>
to <li> {units[0].id}</li>
.
You could also alias it like so, const {units: products} = props
and leave the rest of your code.
After pulling down the repo, there are several issues I found.
// App.js
// Change the code to this,
import React, { useState } from 'react'
import ReactDOM from 'react-dom'
const Unit = ({ unit }) => {
const [title, setCase] = useState(unit.title)
const goUp = () => setCase(String(title).toUpperCase())
const goDown = () => setCase(String(title).toLowerCase())
return (
<div>
<span>
{unit.code} - {title}: {unit.offering}
</span>
<button onClick={goUp}>Up</button>
<button onClick={goDown}>Down</button>
</div>
)
}
const App = ({ units }) => {
return (
<div>
<ul>
{units.map(unit => (
<Unit key={unit.code} unit={unit} />
))}
</ul>
</div>
)
}
export default App
In index.js, change it to this:
import React from 'react'
import ReactDOM from 'react-dom'
import './index.css'
import App from './App'
import * as serviceWorker from './serviceWorker'
const units = [
{ code: 'COMP1010', title: 'Fundamentals of Computer Science', offering: ['S1', 'S2'] },
{ code: 'COMP1750', title: 'Introduction to Business Information Systems', offering: ['S1'] },
{ code: 'COMP2110', title: 'Web Technology', offering: ['S1', 'S2'] },
{ code: 'COMP2750', title: 'Applications Modelling and Development', offering: ['S1'] },
{ code: 'MMCC2045', title: 'Interactive Web Design', offering: ['S2'] },
{ code: 'COMP3120', title: 'Advanced Web Development', offering: ['S2'] },
{ code: 'COMP3130', title: 'Mobile Application Development', offering: ['S1'] }
]
ReactDOM.render(
<React.StrictMode>
<App units={units} />
</React.StrictMode>,
document.getElementById('root')
)
serviceWorker.unregister()
What was happening is this: <App />
was expecting the units to be passed to it so it could pass it to <Unit />
. However, in index.js, you weren't passing in the units
prop. So, I moved the units array to index and passed it in and it worked fine.
Upvotes: 1