Paulos3000 Paulos3000 - 1 month ago 8
React JSX Question

Cannot read property 'props' of undefined (React)

I've got a react component that renders content conditionally, but it's a bit verbose and repetitive. I've tried to wrap the repeated code in a function which I then call later (the output dependent on whatever argument I give the function) but this isn't working.

Original (verbose) solution:



render() {

const userId = parseInt(this.props.params.userId)
const {posts} = this.props

if(userId) {
const postsForUser = posts.filter( post => post.userId === userId )
return (
<div>
{postsForUser.map( post =>
<Post {...this.props} post={post} key={post.id} />
)}
</div>
)
}
else {
return (
<div>
{this.props.posts.map( post =>
<Post {...this.props} post={post} key={post.id} />
)}
</div>
)
}

} // end render()


(Unsuccessful) attempt to trim it down



render() {

const userId = parseInt(this.props.params.userId)

function renderPostList(postsInput) {
return (
<div>
{postsInput.map( post =>
<Post {...this.props} post={post} key={post.id} />
)}
</div>
)
}

if (userId) {
const postsForUser = this.props.posts.filter( post => post.userId === userId )
return renderPostList(postsForUser)
}
else {
return renderPostList(this.props.posts)
}

}


I receive the error:
Cannot read property 'props' of undefined


I know the problem is to do with the function's scope, and how
this
is referencing the wrong this (or nothing, in this case) but I struggle to get my head around how to solve this. If anyone can explain what's going wrong specifically in this instance, I would really appreciate it.

Answer

You should be able to do this by moving the renderPostList method out of the render method and into the class level.

renderPostList = (postsInput) => (
  <div>
    {postsInput.map( post =>
      <Post {...this.props} post={post} key={post.id} />          
    )}
  </div>
)

render() {

  const userId = parseInt(this.props.params.userId)

  if (userId) {
     const postsForUser = this.props.posts.filter( post => post.userId === userId )
     return this.renderPostList(postsForUser)
  }
  else {
     return this.renderPostList(this.props.posts)
  }

}
Comments