React seeing all but on array

react native map array of objects
react map nested array
react loop through array of objects
react: use array.map() to dynamically render elements
react map array of objects
react map push to array
react list example
javascript map

I have a child component that sees all the props but one array that I am trying to map over.

react dev tool sees the array:

but I get "Cannot read property 'map' of undefined"

class Header extends Component {
  render() {
    const nav = this.props.data.nav.map(i => `<li><a href="#${i}">${i}</a></li>`)
    return (
      <div className="header">
        <div className="left">
          <h1>{this.props.data.name}</h1>
          <p>{this.props.data.tag}</p>
        </div>
        <div className="right">
          <h2>{this.props.data.t1}</h2>
          <h3>{this.props.data.t2}</h3>
        </div>
        <div className="header-contact">
          <a rel="noopener" href="tel:+14156943568">
          <FontAwesomeIcon icon={faPhone} /> {this.props.data.phone} 
          </a>
          <a rel="noopener" href="mailto:tim.smith.hdg@gmail.com">
          <FontAwesomeIcon icon="at" /> {this.props.data.email}
          </a>
        </div>
        <nav id="nav" className='nav'>
          <ul>
            {
              //nav
            }
          </ul>
        </nav>
      </div>
    );
  }
}

I'm using the <Header /> component in the follow way:

class Resume extends Component {
  constructor(props) {
    super();
    this.state = { header: {}, skills: {} }
  }
  componentDidMount() {
    this.setState({
        ...data
    });
  }
  render() {
    return (
      <div className="resume">
        <Header data={this.state.header} />
        <Skills data={this.state.skills} />
      </div>
    );
  }
}

You should check that props.data is defined, and that props.data.nav is an array, to address the errors.

The reason you need to perform this check is because the props.data.nav is not present during the first render() of the <Header /> component. This is because the nav data is only available after the componentDidMount() hook in <Resume /> is called (which happens after the first render of <Header />)

You could make the following adjustment to resolve this:

class Header extends Component {

  // [UPDATE] add helper method to simplify safer access to data.nav array
  getNavItems() {

      // If no data, return empty array
      if(!this.props.data) return [];

      // If nav not an array, return empty array
      if(!Array.isArray(this.props.data.nav)) revturn [];

      // Safely access/return nav array
      return this.props.data.nav;
  }

  render() {

    // [UPDATE] use local helper getNavItems method to safely access item array
    const nav = this.getNavItems().map(i => `<li><a href="#${i}">${i}</a></li>`)
    return (
      <div className="header">
        <div className="left">
          <h1>{this.props.data.name}</h1>
          <p>{this.props.data.tag}</p>
        </div>
        <div className="right">
          <h2>{this.props.data.t1}</h2>
          <h3>{this.props.data.t2}</h3>
        </div>
        <div className="header-contact">
          <a rel="noopener" href="tel:+14156943568">
          <FontAwesomeIcon icon={faPhone} /> {this.props.data.phone} 
          </a>
          <a rel="noopener" href="mailto:tim.smith.hdg@gmail.com">
          <FontAwesomeIcon icon="at" /> {this.props.data.email}
          </a>
        </div>
        <nav id="nav" className='nav'>
          <ul>
            {
              //nav
            }
          </ul>
        </nav>
      </div>
    );
  }
}

Is it possible to map only a portion of an array? (Array.map()), map() those portions, but is there a way to .map() a portion of the array without having to break it up? Any and all feedback is appreciated. Thanks! That’s it. You destructure the first item and all the remaining items from the array. Then you use all remaining items to store them in React’s state. The first item isn’t used anymore. All previous array examples worked on an array of integers. Let’s see in a more complex scenario how to remove an object from a React state array

Can you show from where this.props.data.nav comes from? Maybe when the component mounts, this.props.data or this.props.data.nav is undefined. React dev tool shows the array because after the error, this.props.data.nav is already set and not undefined. Try something like:

var nav = null; if(this.props.data != undefined && this.props.data.nav != undefined){ nav = this.props.data.nav.map(i => "<li><a href="#${i}">${i}</a></li>") }

Rendering Arrays in React, But if you check the console, you'll see that React is throwing a a future version of React would stop rendering these components all together! Keys help React identify which items have changed, are added, or are removed. Keys should be given to the elements inside the array to give the elements a stable identity:

You get map is undefined cause you don't get an array. You can't map undefined. The way I will do this will be to get an empty array if I don't have the props yet. This way you can still map over it but receive no element

class Header extends Component {
  render() {
    const navData = this.props.data && this.props.data.nav || []
    const nav = navData.map(i => `<li><a href="#${i}">${i}</a></li>`)
    return (
      <div className="header">
        <div className="left">
          <h1>{this.props.data.name}</h1>
          <p>{this.props.data.tag}</p>
        </div>
        <div className="right">
          <h2>{this.props.data.t1}</h2>
          <h3>{this.props.data.t2}</h3>
        </div>
        <div className="header-contact">
          <a rel="noopener" href="tel:+14156943568"><FontAwesomeIcon icon={faPhone} /> {this.props.data.phone}</a>
          <a rel="noopener" href="mailto:tim.smith.hdg@gmail.com"><FontAwesomeIcon icon="at" /> {this.props.data.email}</a>
        </div>
        <nav id="nav" className='nav'>
          <ul>
            {
              //nav
            }
          </ul>
        </nav>
      </div>
    );
  }
}

Or you can handle this case from the parent also

class Parent extends Component {
  render() {
    return (
      <div>
        <Header data={this.state.header} nav={this.state.header && this.state.header.nav || []} /> 
      </div>
    )
  }
}


class Header extends Component {
  render() {
    const nav = this.props.nav.map(i => `<li><a href="#${i}">${i}</a></li>`)
    return (
      <div className="header">
        <div className="left">
          <h1>{this.props.data.name}</h1>
          <p>{this.props.data.tag}</p>
        </div>
        <div className="right">
          <h2>{this.props.data.t1}</h2>
          <h3>{this.props.data.t2}</h3>
        </div>
        <div className="header-contact">
          <a rel="noopener" href="tel:+14156943568"><FontAwesomeIcon icon={faPhone} /> {this.props.data.phone}</a>
          <a rel="noopener" href="mailto:tim.smith.hdg@gmail.com"><FontAwesomeIcon icon="at" /> {this.props.data.email}</a>
        </div>
        <nav id="nav" className='nav'>
          <ul>
            {
              //nav
            }
          </ul>
        </nav>
      </div>
    );
  }
}

Modern Full-Stack Development: Using TypeScript, React, Node.js, , Using TypeScript, React, Node.js, Webpack, and Docker Frank Zammetti to one of the imported image modules (see, I told you we're using those like code!). Each also gets the className, which is blank for all but the highlighted tile, if any​. Once all the tiles have been pushed into the tiles array, we can finally return the  I just started to learn React and I am trying to figure out how to find a specific value I am looking for. Just like you have the each.do method in Ruby and you can iterate through an array, I'm trying to do that with React.

React: Tools & Resources, To see all this in action, we need to start coding. However, if you're working with Arrays and Objects, performing mutable operations don't actually hold values themselves, but are pointers to a memory location where the values are stored. But if you check the console, you’ll see that React is throwing a warning about the children lacking keys. Using unique keys on collections of components is how React knows what to re-render and not re-render when the data changes.

How to Display a List in React, function NonIdiomaticList(props) { // Build an array of items let array This works, but it's a lot of lines of code to accomplish the task. This is actually not a great idea in all cases, and I'll tell you why. The first time a component like IdiomaticReactList is rendered, React will see that you want to render a  All the methods in this article are chainable, meaning they can be used in combination with one another and they also don’t mutate data, which is especially important when working with React. With all these array and object methods you’ll find you never have to reach for a for or while loop ever again.

Lists and Keys – React, Given the code below, we use the map() function to take an array of numbers and Keys serve as a hint to React but they don't get passed to your components. What’s the “React way” to render a list? The good news is it’s pretty simple. All you need is Array.map. The Non-React Way to Render a List. If you’re not accustomed to functional programming yet, your first inclination to render a list might be to create a new array, then iterate over the list and push JSX elements into it.

Comments
  • it is seen as an object
  • @Tithos correct, data is an object - did the above solution work for you?
  • class Resume extends Component { constructor(props) { super(); this.state = { header: {}, skills: {} } } componentDidMount() { this.setState({ ...data }); } render() { return ( <div className="resume"> <Header data={this.state.header} /> <Skills data={this.state.skills} /> </div> ); } }
  • Have you tried the code I wrote above, any error or changes? Can you log the contents of this.props in render method of the Header component?
  • I can't see any difference in your answer comparing to mine. Can you explain?
  • @PedroSimão o sorry, I didn't refresh my screen and I didn't see your answer. My bad sorry. Gonna upvote your :)