0

From this code, (that works). I use map to render the array named parts. code in sandbox

import React from 'react'


const Header = (props) => {
  //console.log(props)
  //I pass the whole object (course) as props and use only name
  return (
    <div>
    {   <h1>{props.course.name}</h1> }
    </div>
  )
}


  const App = () => {
    
    const course = {
      id: 1,
      name: 'Half Stack application development',
    
      parts: [
        {
          name: 'Fundamentals of React',
          exercises: 10,
          id: 1
        },
        {
          name: 'Using props to pass data',
          exercises: 7,
          id: 2
        },
        {
          name: 'State of a component',
          exercises: 14,
          id: 3
        }
      ]

    }
    
   




  
    
  return (
    <div>
        
        <Header  course={course} />
       
      <ul>
      {course.parts.map(part => 
          <li key={part.id}>
            {part.name} {part.exercises}
          </li>
        )}
      </ul>
    
      
  
      
  
    </div>
  )
}

export default App

I want to define a separate component responsible of rendering the contents of the array parts.

parts: [
        {
          name: 'Fundamentals of React',
          exercises: 10,
          id: 1
        },
        {
          name: 'Using props to pass data',
          exercises: 7,
          id: 2
        },
        {
          name: 'State of a component',
          exercises: 14,
          id: 3
        }

I tried this. I checked for the props with console.log, and they are there. But I get the error

ReferenceError course is not defined.

There is something I am doing wrong, but I can't figure out what.

code sandbox

import React from 'react'


const Header = (props) => {
  //console.log(props)
  //I pass the whole object (course) as props and use only name
  return (
    <div>
    {   <h1>{props.course.name}</h1> }
    </div>
  )
}

const Courses = (props) => {
  console.log(props)
  //I pass the whole object (course) as props
  return (
    <div>
    <ul>
      {course.parts.map(part => 
          <li key={part.id}>
            {part.name} {part.exercises}
          </li>
        )}
      </ul>
    </div>
  )
}

  const App = () => {
    
    const course = {
      id: 1,
      name: 'Half Stack application development',
    
      parts: [
        {
          name: 'Fundamentals of React',
          exercises: 10,
          id: 1
        },
        {
          name: 'Using props to pass data',
          exercises: 7,
          id: 2
        },
        {
          name: 'State of a component',
          exercises: 14,
          id: 3
        }
      ]

    }
    
    //const Result = course.parts.map(parts => <li key={parts.id}>{parts.name}</li>)
    //console.log(Result)




  
    
  return (
    <div>
        
      <Header  course={course} />
       
      <Courses  course={course} />
    
      
  
      
  
    </div>
  )
}

export default App
3
  • Please add a minimal reproducible example since both sandboxes are empty.... Also you can create an inline react snippet/ Commented May 11, 2021 at 16:20
  • if you pass it as props, use props.course not just course Commented May 11, 2021 at 16:22
  • First thought: course.parts.map should be props.course.parts.map Commented May 11, 2021 at 16:22

3 Answers 3

2

You didn't destructure your props properly in your Courses component. Check out the Mozilla docs for more information on ES6 destructuring. It will clean up your React code by a lot!

import React from "react";

const Header = ({ course }) => {
  const { name } = course;
  return (
    <div>
      <h1>{name}</h1>
    </div>
  );
};

const Courses = ({ course }) => {
  const { parts } = course;
  return (
    <div>
      <ul>
        {parts.map(({ id, name, exercises }) => (
          <li key={id}>
            {name} {exercises}
          </li>
        ))}
      </ul>
    </div>
  );
};

const course = {
  …
};

const App = () => (
  <div>
    <Header course={course} />
    <Courses course={course} />
  </div>
);

export default App;

You can even destructure two levels deep and use the implicit arrow function return, depending on what you find most readeable.

const Header = ({ course: { name } }) => (
  <div>
    <h1>{name}</h1>
  </div>
);

By the way, you don't need to wrap your data in a react component. It can live anywhere in your document, or ideally be imported from a separate json file.

Sign up to request clarification or add additional context in comments.

Comments

2

You forgot to include props before course keyword. Code should looks like this:

const Header = (props) => {
  //console.log(props)
  //I pass the whole object (course) as props and use only name
  return <div>{<h1>{props.course.name}</h1>}</div>;
};

const Courses = (props) => {
  console.log(props);
  //I pass the whole object (course) as props
  return (
    <div>
      <ul>
        {props.course.parts.map((part) => (
          <li key={part.id}>
            {part.name} {part.exercises}
          </li>
        ))}
      </ul>
    </div>
  );
};

const App = () => {
  const course = {
    id: 1,
    name: "Half Stack application development",

    parts: [
      {
        name: "Fundamentals of React",
        exercises: 10,
        id: 1
      },
      {
        name: "Using props to pass data",
        exercises: 7,
        id: 2
      },
      {
        name: "State of a component",
        exercises: 14,
        id: 3
      }
    ]
  };

  //const Result = course.parts.map(parts => <li key={parts.id}>{parts.name}</li>)
  //console.log(Result)

  return (
    <div>
      <Header course={course} />

      <Courses course={course} />
    </div>
  );
};

Note that you can use it the way you used it by destructuring the props:

const Courses = ({ course }) => {}

Then you would be able to use it as you did in your code without props keyword beforehand.

Comments

1

Just you are missing the props, you try to call courses from Course component direct, so that when you add the props before, all is work fine..

<ul>
      {props.course.parts.map(part => 
          <li key={part.id}>
            {part.name} {part.exercises}
          </li>
        )}
      </ul>

Full code:

import React from 'react'


const Header = (props) => {
  //console.log(props)
  //I pass the whole object (course) as props and use only name
  return (
    <div>
    {   <h1>{props.course.name}</h1> }
    </div>
  )
}

const Courses = (props) => {
  console.log(props)
  //I pass the whole object (course) as props
  return (
    <div>
    <ul>
      {props.course.parts.map(part => 
          <li key={part.id}>
            {part.name} {part.exercises}
          </li>
        )}
      </ul>
    </div>
  )
}

  const App = () => {
    
    const course = {
      id: 1,
      name: 'Half Stack application development',
    
      parts: [
        {
          name: 'Fundamentals of React',
          exercises: 10,
          id: 1
        },
        {
          name: 'Using props to pass data',
          exercises: 7,
          id: 2
        },
        {
          name: 'State of a component',
          exercises: 14,
          id: 3
        }
      ]

    }
    
    //const Result = course.parts.map(parts => <li key={parts.id}>{parts.name}</li>)
    //console.log(Result)




  
    
  return (
    <div>
        
      <Header  course={course} />
       
      <Courses  course={course} />
    
      
  
      
  
    </div>
  )
}

export default App

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.