ElJefeJames ElJefeJames - 1 month ago 22
React JSX Question

How do I access nested object properties within React props

Following on from this question - Javascript - How do I access properties of objects nested within other Objects

Standard dot notation doesn't seem to work for accessing nested object properties within React state/props

That is given props below: How do I retrieve the latitude?

Object {
id: "138451",
name: "Attendant",
key: "Taiwan",
defaultAnimation: 2,
position: Object
{
latitude:0.5,
longitude: -0.14
}
componentWillReceiveProps(nextProps){
console.log("its getting props");
console.log(nextProps.markers[0]) // this works
//displays Object {position: Object, key: 2, defaultAnimation: 2}
console.log(nextProps.markers[0].position) //so does this
//displays Object {latitude: 51.5193, longitude: -0.140725}
console.log(nextProps.markers[0].position.longitude) //breaks with the error message

TypeError: Cannot read property 'longitude' of undefined
at GooleMapComponent.componentWillReceiveProps (http://localhost:3000/app/app.js?....

Answer

Here is a demo of how you can use dot notation to access nested object properties within React props both in Child's componentWillReceiveProps method as well as in the render() method: http://codepen.io/PiotrBerebecki/pen/qaKyYj

class App extends React.Component {
  constructor() {
    super();
    this.handleClick = this.handleClick.bind(this);
    this.state = {
      markers: null
    }
  }

  handleClick() {
    this.setState({
      markers: [
        { 
          id: "138451",
          name: "Attendant",
          key: "Taiwan", 
          defaultAnimation: 2, 
          position: {
            latitude: 0.5,
            longitude: (-Math.random()).toFixed(2)
          }
        }
      ]
    });
  }  

  render() {
    return (
      <div>
        <h1>App</h1>
        <button onClick={this.handleClick}>Send State via Props</button>
        <Child markers={this.state.markers}/>     
      </div>
    );
  }
}

class Child extends React.Component {
  componentWillReceiveProps(nextProps) {
    console.clear();
    console.log('in componentWillReceiveProps', nextProps.markers[0]);
    console.log('in componentWillReceiveProps', nextProps.markers[0].position);
    console.log('in componentWillReceiveProps', nextProps.markers[0].position.longitude);
  }

  render() {
    if (this.props.markers) {
      return (
       <div>
          <h5>Child happy :) child received an array via props</h5>
          Longitute: {this.props.markers[0].position.longitude}
       </div>
      );
    } else {
      return (
       <div>
          <h5>Child not happy :( Child received 'null' via props</h5>
       </div>
     );
    }
  }
}

ReactDOM.render(
  <App />,
  document.getElementById('app')
);