Reputation: 672
I have the following component in react
import React, { Component } from 'react';
import axios from 'axios'
import Post from './Post'
import Navbar from '../Navbar'
class SinglePost extends Component {
constructor(props) {
super(props);
this.state = {
post: {}
}
}
componentDidMount() {
const { post_id } = this.props.match.params
axios.get(`http://127.0.0.1:8000/posts/${post_id}`)
.then(res => {
this.setState({ post: res.data })
console.log(res.data)
console.log(this.state)
})
.catch(err => console.log(err))
}
render() {
return (
<div>
<Navbar />
<div style={{height: '95px'}}></div>
<Post key={this.state.post.id} post={this.state.post} />
</div>
)
}
}
export default SinglePost;
The correct response is recieved from the backend and set to state properly. However the data passed to the Post component shows up as undefined.
Here is teh post component:
import React from 'react'
import Comment from './Comment'
import CommentForm from './CommentForm'
const placeholder_url = 'https://image.shutterstock.com/image-vector/ui-image-placeholder-wireframes-apps-260nw-1037719204.jpg'
const placeholder = 'data:image/png;base64,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'
function Post(props) {
console.log(props) //Shows up as an empty object
return (
<div className="uk-background-muted uk-margin-top uk-container">
<div>
<div className="uk-background-default">
<img src={props.post.user.pp || placeholder} width="50" height="50" alt={props.post.user.username} />
<a href={`/users/${props.post.user.id}`}>{props.post.user.username}</a>
</div>
<img className="uk-align-center" src={props.post.image || placeholder_url} alt="placeholder" />
<ul>
<li>Likes: {props.post.post_liked.length}</li>
<li>Dislikes: {props.post.post_disliked.length}</li>
<li>Comments: {props.post.comment_post.length}</li>
</ul>
<p className="uk-text-large">{props.post.text}</p>
{props.post.comment_post.map(comment => (<Comment key={comment.id} comment={comment} />))}
<div>
<CommentForm key={props.post.id} post={props.post} />
</div>
</div>
</div>
)
}
export default Post
This is the error I get: TypeError: Cannot read property 'pp' of undefined
Upvotes: 1
Views: 257
Reputation: 4873
The error happens in the first render when post = {}
and the Post component is trying to get props.post.user.pp
.
To solve the problem, in the SinglePost
component, you could initialize post
to be null
instead of {}
and in the Post
component, handle the post === null
case:
function Post(props) {
if(!props.post) {
return null;
// return <span>Loading</span>;
}
return (
<div className="uk-background-muted uk-margin-top uk-container">
...
Upvotes: 1
Reputation: 2711
State-setting is asynchronous, so whenever you want to act upon data from state, you should include a manual check against undefined values.
Try something like this:
class SinglePost extends Component {
constructor(props) {
super(props);
this.state = {
post: null // null initial value is easier to check than an empty object
}
}
componentDidMount() {
const { post_id } = this.props.match.params
axios.get(`http://127.0.0.1:8000/posts/${post_id}`)
.then(res => {
this.setState({ post: res.data })
console.log(res.data)
console.log(this.state)
})
.catch(err => console.log(err))
}
render() {
return (
<div>
<Navbar />
<div style={{height: '95px'}}></div>
{this.state.post &&
<Post key={this.state.post.id} post={this.state.post} />
}
</div>
)
}
}
Upvotes: 1