Koala7 Koala7 - 1 month ago 11
React JSX Question

Uncaught TypeError: Cannot read property 'props' of null in React Class

I have refactored a component and i am not using

React.createClass
in class methods anymore but i have this error now

{this.props.removeComment.bind(null, this.props.params.svgId, i)}



TypeError: Cannot read property 'props' of undefined


The code was perfectly working

Before the refactor

import React from 'react';

const Comments = React.createClass({
renderComment(comment, i) {
return (
<div className="comment" key={i}>
<p>
<strong>{comment.user}</strong>
{comment.text}
<button className="remove-comment" onClick={this.props.removeComment.bind(null, this.props.params.svgId, i)}>&times;</button>
</p>
</div>
)
},

handleSubmit(e) {
e.preventDefault();
const { svgId } = this.props.params;
const author = this.refs.author.value;
const comment = this.refs.comment.value;
this.props.addComment(svgId, author, comment);
this.refs.commentForm.reset();
},

render() {
return (
<div className="comments">
{this.props.svgComments.map(this.renderComment)}
<form ref="commentForm" className="comment-form" onSubmit={this.handleSubmit}>
<input type="text" ref="author" placeholder="author"/>
<input type="text" ref="comment" placeholder="comment"/>
<input type="submit" hidden />
</form>
</div>
)
}
});

export default Comments;


Now after the refactor

import React from 'react';

export default class Comments extends React.Component {
renderComment(comment, i) {
return (
<div className="comment" key={i}>
<p>
<strong>{comment.user}</strong>
{comment.text}
<button className="remove-comment" onClick={this.props.removeComment.bind(null, this.props.params.svgId, i)}>&times;</button>
</p>
</div>
)
};

handleSubmit(e) {
e.preventDefault();
const { svgId } = this.props.params;
const author = this.refs.author.value;
const comment = this.refs.comment.value;
this.props.addComment(svgId, author, comment);
this.refs.commentForm.reset();
};

render() {
return (
<div className="comments">
{this.props.svgComments.map(this.renderComment)}
<form ref="commentForm" className="comment-form" onSubmit={this.handleSubmit}>
<input type="text" ref="author" placeholder="author"/>
<input type="text" ref="comment" placeholder="comment"/>
<input type="submit" hidden />
</form>
</div>
)
}
};


So how can i manually bind
this
in class constructor ?

Answer

you need to bind the methods to the component instance in the constructor like so

export default class Comments extends React.Component {
  constructor() {
    super();

    this.renderComment = this.renderComment.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

if you are using babel with stage-2 you can also refactor your methods and just do the following:

renderComment = (comment, i) => {
  // code goes here    
}

handleSubmit = (e) => {
  // code goes here
}

i prefer the second way as its much cleaner but have to have the right plugin for babel for it to work properly.

What this is doing is making sure when these functions are called, they are called with this being bound to the component.