Получение TypeError: this.props undefined на ReactJs
Я пытаюсь сделать учебник: https://facebook.github.io/react/docs/tutorial.html
import React, { PropTypes } from 'react';
import classnames from 'classnames';
import styles from './CommentBox.css';
import withStyles from '../../decorators/withStyles';
import Link from '../../utils/Link';
import $ from 'jquery';
@withStyles(styles)
class CommentBox extends React.Component {
constructor() {
super();
this.state = {data: []};
}
loadCommentsFromServer() {
$.ajax({
url: this.props.url,
dataType: 'json',
cache: false,
success: function(data) {
this.setState({data: data});
}.bind(this),
error: function(xhr, status, err) {
console.error(this.props.url, status, err.toString());
}.bind(this)
})
}
componentDidMount() {
this.loadCommentsFromServer();
setInterval(this.loadCommentsFromServer, this.props.pollInterval);
}
render() {
let url="/public/comments.json"
return (
<div className="commentBox">
<h1>Comments</h1>
<CommentList data={this.state.data} />
<CommentForm />
</div>
);
}
}
class CommentList extends React.Component {
render() {
let data = this.props.data
var commentNodes = data.map(function (comment) {
return (
<Comment author={comment.author}>
{comment.text}
</Comment>
);
});
return (
<div className="commentList">
{commentNodes}
</div>
);
}
};
class Comment extends React.Component {
render() {
return(
<div className="comment">
<h2 className="commentAuthor">
{this.props.author}
</h2>
{this.props.children}
</div>
);
}
}
class CommentForm extends React.Component {
render() {
return (
<div className="commentForm">
Hello, world! I am a CommentForm.
</div>
);
}
};
export default CommentBox;
Однако учебник немного устарел, и я использую React 0.14-rc1 с синтаксисом ES6. Я изо всех сил старался следовать этому руководству и реализовывать его с использованием метода 0.14. Был в состоянии добраться до этого момента, но теперь получил ошибку:
TypeError: this.props is undefined
Не удалось выяснить проблему. Любая идея почему? Благодаря
Ответы
Ответ 1
При использовании React и классы ES6 Реагировать не будет автоматически связывать функции, объявленные в вашем классе.
Поэтому используйте this.loadCommentsFromServer.bind(this)
или используйте функции стрелок
loadCommentsFromServer = () => {}
Ответ 2
При смещении React от createClass до ES6 classes
нам нужно обрабатывать правильное значение this
для наших методов самостоятельно, как указано здесь: http://www.newmediacampaigns.com/blog/refactoring-react-components-to-es6-classes
Измените свой код, чтобы метод был ограничен, чтобы исправить его значение в конвейере:
export default class ComponentClass extends React.Component {
constructor(props) {
super(props);
this._myHandler = this._myHandler.bind(this);
}
_myHandler(props) {
console.log(props);
}
render() {
return (
<div className="col-xs-6 col-md-4">
<button type="button" className="btn btn-danger" onClick={this._myHandler}><i className="fa fa-trash"> Delete</i></button>
</div>
)
}
}
no autobinding
был преднамеренным шагом от ребят Реагента для классов ES6. Автообъект для правильного контекста был предоставлен React.createClass
. Подробности можно найти здесь: https://facebook.github.io/react/blog/2015/01/27/react-v0.13.0-beta-1.html#autobinding
Таким образом, на основе этого вы также можете изменить свой код как:
export default class ComponentClass extends React.Component {
_myHandler = (props) => {
console.log(props);
}
render() {
return (
<div className="col-xs-6 col-md-4">
<button type="button" className="btn btn-danger" onClick={this._myHandler}><i className="fa fa-trash"> Delete</i></button>
</div>
)
}
}
Ответ 3
Передача props
конструктору поможет:
constructor(props) {
super(props);
}
Ответ 4
Хотя все вышеперечисленные ответы технически правильны, они не работали в моем случае. Я получил некоторую сумасшедшую ошибку "Отсутствие свойств свойств класса", поэтому вместо того, чтобы пытаться понять это, я определил обработчик прямо в этом случае:
export class ComponentClass extends React.Component{
_myHandler(event) {
event.preventDefault();
console.log(this.props.thingIPassedIn);
}
render() {
return <Button onClick={(event) => this._myHandler(event)} type="button" className="btn btn-danger">Click Me!</Button>;
}
}
Вы также можете передавать параметры таким образом.
export class ComponentClass extends React.Component{
_myHandler(thingIPassedIn) {
console.log(thingIPassedIn);
}
render() {
return <MyOtherComponent defNotAnEvent={(thingIPassedIn) => this._myHandler(thingIPassedIn)} />;
}
}
Ответ 5
Ajax-код можно улучшить, как показано ниже, используя функцию стрелки, чтобы избежать проблем с областью видимости и получить доступ к реквизиту
loadCommentsFromServer = () => {
$.ajax({
url: this.props.url,
dataType: 'json',
cache: false,
success: (data) => {
this.setState({data: data});
},
error: (xhr, status, err) => {
console.error(this.props.url, status, err.toString());
}
})
}
Ответ 6
Я также новичок в React, и одна вещь, на которую стоит обратить внимание при работе с состоянием и опорами внутри функции - ИСПОЛЬЗУЕТСЯ ПЕРЕМЕННОЙ ФУНКЦИИ, т.е.
func(){this.setState}
ошибка результата func=()=>{this.setState}
будет работать
То же самое в случае с
this.props
внутри функции
Обратите внимание, что даже вы не используете function.bind(this) с его контекстом внутри конструктора.