CoopDaddio
CoopDaddio

Reputation: 637

TypeError: undefined for array in React

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

Answers (2)

Yatrix
Yatrix

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.

Edit

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

Bhuwan Adhikari
Bhuwan Adhikari

Reputation: 1009

Use const products = props.units instead.

Upvotes: 0

Related Questions