Can't access nested object properties in a single object from JSON call in REACT

邮差的信 提交于 2021-02-20 19:15:49

问题


I'm making an Rails API call and return a single JSON object that has a nested User Object and a tag list array. However, I can't access the nested Object.

this.props.post.user.name throws: Cannot read property 'name' of undefined.

I am confused because when I make the call to PostsIndex in PostsIndex.js and get an array of objects and map through it I can access everything.

Is there something I need to do when only dealing with a single object?

PostShow.js

import React, {Component} from 'react';
import axios from 'axios';
import {Link} from 'react-router-dom';



export default class PostShow extends Component {

constructor(props) {
  super(props)
  this.state = {
    post: {}
  };
}

componentDidMount() {
  const { match: { params } } = this.props;
  axios
    .get(`/api/posts/${params.postId}`)
    .then(response => {
      console.log(response);
      this.setState({ post: response.data});
    })
    .catch(error => console.log(error));

}

  render() {
    return (
      <div>
            <Post post={this.state.post}/>
      </div>
    );
  }
}

class Post extends Component {

  constructor(props) {
    super(props)
  }

  render() {

    return (
      <div>
        <div className="centered">
          <small className ="small" >  | Posted by: {this.props.post.user.name}  on   | Tags:  </small>
          <h3>{this.props.post.title}</h3>
          <img className="image " src={this.props.post.image}/>
        </div>
        <div>
          <p className = "songTitle"> {this.props.post.song_title} </p>
          <p className= "postBody"> {this.props.post.body} </p>
          <div className = "link" dangerouslySetInnerHTML={{ __html: this.props.post.link }} />
        </div>
      </div>
    );
  }
} 

Here is what the JSON object looks like from /api/posts/7:

{"id":7, "title":"adgaadg", "body":"adgadgagdgd", "post_type":"Video", "tag_list":["ERL"], "image":"/images/original/missing.png", "song_title":"adgdgdgd", "created_at":"2018-08-11T21:57:00.447Z", "user":{"id":2,"name":"John","bio":"bio","location":"Reno"}}


回答1:


That's because this.props.post.user will be undefined before your request has finished, and trying to access name on that will give rise to your error.

You could e.g. set the initial post to null and not render anything until your request is complete.

Example

class PostShow extends Component {
  constructor(props) {
    super(props);
    this.state = {
      post: null
    };
  }

  componentDidMount() {
    const {
      match: { params }
    } = this.props;
    axios
      .get(`/api/posts/${params.postId}`)
      .then(response => {
        console.log(response);
        this.setState({ post: response.data });
      })
      .catch(error => console.log(error));
  }

  render() {
    const { post } = this.state;

    if (post === null) {
      return null;
    }

    return (
      <div>
        <Post post={post} />
      </div>
    );
  }
}



回答2:


axios.get is an async operation and <Post post={this.state.post}/> renders before this.setState({ post: response.data}); which means when Post component renders this.state.post is empty object. So what you can do is, initialize your post with null in constructor

this.state = {
   post: null
};

and instead of <Post post={this.state.post}/> do {this.state.post && <Post post={this.state.post}/>} it will render post only if its exists and not null.



来源:https://stackoverflow.com/questions/51804796/cant-access-nested-object-properties-in-a-single-object-from-json-call-in-react

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!