简体   繁体   中英

React component wont map array

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')
  );

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

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"));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM