0

Just starting to learn React now and I cannot seem to get the Planet component to display the attibutes after mapping over the planet array. Even when I console.log something from the Planet component it comes up as undefined. Obviously I'm screwing something up between my App component and my Planet component but I cannot figure out what.

const planets = [
  {
    id: '1',
    name: 'Mercury',
    diameter: '3,031.67 mi',
    moons: 'none',
    desc: 'Mercury is the closest planet to the Sun. Due to its proximity, it\'s not easily seen except during twilight. For every two orbits of the Sun, Mercury completes three rotations about its axis. Up until 1965 it was thought that the same side of Mercury constantly faced the Sun.',
    url: 'img/mercury.jpg' 
  },
  {
    id: '2',
    name: 'Venus',
    diameter: '7,521 mi',
    moons: 'none',
    desc: 'Venus is the second planet from the Sun and is the second brightest object in the night sky after the Moon. Venus is the second largest terrestrial planet and is sometimes referred to as the Earth’s sister planet due the their similar size and mass.',
    url: 'img/venus.jpg' 
  },
  {
    id: '3',
    name: 'Earth',
    diameter: '7,917.5 mi',
    moons: '1',
    desc: 'Earth is the third planet from the Sun and is the largest of the terrestrial planets. The Earth is the only planet in our solar system not to be named after a Greek or Roman deity. The Earth was formed approximately 4.54 billion years ago and is the only known planet to support life.',
    url: 'img/earth.jpg' 
  },
  {
    id: '4',
    name: 'Mars',
    diameter: '4,212 mi',
    moons: '2',
    desc: 'The fourth planet from the Sun and the second smallest planet in the solar system. Mars is often described as the "Red Planet" due to its reddish appearance. It\'s a terrestrial planet with a thin atmosphere composed primarily of carbon dioxide.',
    url: 'img/mars.jpg'
  },
  {
    id: '5',
    name: 'Jupiter',
    diameter: '86,881.4 mi',
    moons: '79',
    desc: 'The planet Jupiter is the fifth planet out from the Sun, and is two and a half times more massive than all the other planets in the solar system combined. It is made primarily of gases and is therefore known as a "gas giant".',
    url: 'img/jupiter.jpg' 
  },
  {
    id: '6',
    name: 'Saturn',
    diameter: '72,367.4 mi',
    moons: '62',
    desc: 'Saturn is the sixth planet from the Sun and the most distant that can be seen with the naked eye. Saturn is the second largest planet and is best known for its fabulous ring system that was first observed in 1610 by the astronomer Galileo Galilei.',
    url: 'img/saturn.jpg'
  },
  {
    id: '7',
    name: 'Uranus',
    diameter: '31,518 mi',
    moons: '27',
    desc: 'Uranus is the seventh planet from the Sun. While being visible to the naked eye, it was not recognised as a planet due to its dimness and slow orbit. Uranus became the first planet discovered with the use of a telescope.',
    url: 'img/uranus.jpg' 
  },
  {
    id: '8',
    name: 'Neptune',
    diameter: '30,599 mi',
    moons: '14',
    desc: 'Neptune is the eighth planet from the Sun making it the most distant in the solar system. This gas giant planet may have formed much closer to the Sun in early solar system history before migrating to its present position.',
    url: 'img/neptune.jpg' 
  },
];


   const App = (props) => {
  return (
  <Container planets={props.planets} >

    {props.planets.map((planet) => {
    return ( <Planet
      name={planet.name}
      key={planet.id.toString()} 
      name={planet.name} 
      diameter={planet.diameter} 
      moons={planet.moons}
      desc={planet.desc}
      url={planet.url}

      />)
  })}

  </Container>
  );
  }

  const Planet = (props) => {
         console.log(props.url)
      return (
       <div className="card">
        <div>
          <img src={props.url} alt={props.name} />
        </div>
        <h2>{props.name}</h2>
        <p>{props.desc}</p>
        <h3>Planet Profile</h3>
        <ul>
          <li><strong>Diameter:</strong>{props.diameter}</li>
          <li><strong>Moons:</strong> {props.moons}</li>
        </ul>
      </div>
  );
  };


  const Container = (props) => {
  console.log(props.planets.length)
    return (
      <div className="container">
        <Planet planets={props.planets} 
      />
      </div>
  );
  };


  ReactDOM.render(
    <App planets={planets}  />,
    document.getElementById('root')
  );
1
  • did you log props object? If yes, what does that contain? Commented Sep 18, 2019 at 1:45

2 Answers 2

1

Your Container component is not rendering its children

const Container = props => {
  return (
    <div className="container">
      <Planet planets={props.planets} />
    </div>
  );
};

Notice between the div tags, you are only rendering one Planet component.

You probably should change it to:

const Container = props => {
  return (
    <div className="container">{props.children}</div>
  );
};

So in your App component, you can use the map function now.

    <Container>
      {props.planets.map(planet => {
        return (
          <Planet
            name={planet.name}
            key={planet.id.toString()}
            name={planet.name}
            diameter={planet.diameter}
            moons={planet.moons}
            desc={planet.desc}
            url={planet.url}
          />
        );
      })}
    </Container>

See everything between the Container tags - will be provided as props.children to the Container component.

You can learn more about it here: https://reactjs.org/docs/composition-vs-inheritance.html

There are lots of other good articles that talk about React's children prop - just google React props.children

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

3 Comments

Wow! thank you so much! that solved the problem I was having! I just started learning react a few days ago, so I didn't even know props.children was actually a valid method in React you could use in order to pass data from the parent component to the children component(s).
Hmmm usually you don't pass data via props.children though - it's just a way for you to compose your components. Your data is provided to the component via props, when you render them, in this case it is in App. Your Container doesn't need to receive planets. react official docs site has many good articles, good luck with your react adventure!
gotcha, yeah I'm still learning as you can tell so my terminology may be off, but I see what you mean regarding the fact that its a way for you to compose the components and children. I can see how this would be very useful
0

Perhaps you are missing something while passing data. Moreover, your code is redundant and may crash at some points. Do proper de-structuring with necessary safety checks. Moreover, Container should receive list of planets (array) while Planet component should receive only one item of planets array, not the whole array. Use this piece of code. I have posted it after testing. I hope you'll get some good points to learn from this code.

const App = props => {
  // destructuring data with extra safety checks to prevent code crashes
  const { planets = [] } = props || {};
  return <Container planets={planets} />;
};

const Container = props => {
  // adding extra guards to prevent code crashes
  const { planets = [] } = props || {};
  return (
    <div className="container">
      {planets && planets.map(planet => <Planet planet={planet} />)}
    </div>
  );
};

const Planet = props => {
  const { planet = {} } = props || {};
  return (
    <div className="card">
      <div>
        <img src={planet.url} alt={planet.name} />
      </div>
      <h2>{planet.name}</h2>
      <p>{planet.desc}</p>
      <h3>Planet Profile</h3>
      <ul>
        <li>
          <strong>Diameter:</strong>
          {planet.diameter}
        </li>
        <li>
          <strong>Moons:</strong> {planet.moons}
        </li>
      </ul>
    </div>
  );
};

ReactDOM.render(<App planets={planets} />, document.getElementById("root"));

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.