Uncaught TypeError: Cannot read property 'props' of null in React Class
Uncaught TypeError: Cannot read property 'props' of null in React Class
我已经重构了一个组件,我不再在 class 方法中使用 React.createClass
但我现在有这个错误
{this.props.removeComment.bind(null, this.props.params.svgId, i)}
TypeError: Cannot read property 'props' of undefined
代码运行良好
重构前
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)}>×</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;
现在重构后
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)}>×</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>
)
}
};
那么我如何在 class 构造函数中手动绑定 this
呢?
你应该有一个构造函数,调用 super()
并在那里绑定方法
React.createClass 自动将它绑定到组件,在 ES6 class 中你必须手动创建它,并且在调用 super()
之前你不能使用 this
您需要像这样在构造函数中将方法绑定到组件实例
export default class Comments extends React.Component {
constructor() {
super();
this.renderComment = this.renderComment.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
如果你在 stage-2 中使用 babel,你也可以重构你的方法,只需执行以下操作:
renderComment = (comment, i) => {
// code goes here
}
handleSubmit = (e) => {
// code goes here
}
我更喜欢第二种方式,因为它更干净,但必须有正确的 babel 插件才能正常工作。
这样做是为了确保在调用这些函数时,它们是通过 this
绑定到组件来调用的。
我已经重构了一个组件,我不再在 class 方法中使用 React.createClass
但我现在有这个错误
{this.props.removeComment.bind(null, this.props.params.svgId, i)}
TypeError: Cannot read property 'props' of undefined
代码运行良好
重构前
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)}>×</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;
现在重构后
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)}>×</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>
)
}
};
那么我如何在 class 构造函数中手动绑定 this
呢?
你应该有一个构造函数,调用 super()
并在那里绑定方法
React.createClass 自动将它绑定到组件,在 ES6 class 中你必须手动创建它,并且在调用 super()
之前你不能使用 this
您需要像这样在构造函数中将方法绑定到组件实例
export default class Comments extends React.Component {
constructor() {
super();
this.renderComment = this.renderComment.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
如果你在 stage-2 中使用 babel,你也可以重构你的方法,只需执行以下操作:
renderComment = (comment, i) => {
// code goes here
}
handleSubmit = (e) => {
// code goes here
}
我更喜欢第二种方式,因为它更干净,但必须有正确的 babel 插件才能正常工作。
这样做是为了确保在调用这些函数时,它们是通过 this
绑定到组件来调用的。