Lahey Corey
Lahey Corey

Reputation: 103

Use map on a reactjs component

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

Upvotes: 0

Views: 58

Answers (3)

msalla
msalla

Reputation: 765

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.

Upvotes: 2

Stefan
Stefan

Reputation: 260

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.

Upvotes: 2

Anees Hikmat Abu Hmiad
Anees Hikmat Abu Hmiad

Reputation: 3560

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

Upvotes: 1

Related Questions