user3055526 user3055526 - 2 months ago 16
CoffeeScript Question

cannot read property "names" of undefined in react

I'm writing reactjs (coffescript+JSX syntax). If user writes something into input and then clicks on the button, get ajax request is sent and the result in callback function (json object) isn't inserted into the state names using setState and I get following error: cannot read property "names" of undefined

I don't know where should be a problem

$ ->
# first component
MainComponent = React.createClass
getInitialState: ->
names:[]

_getSpecificCard: (card_name) ->
$.get "home/users/#{card_name}", (newuser) -> @setState names:@state.names.concat([newuser])

_getAllcards: ->
@state.names.map((user) ->
<Card key={user.id} name={user.login} avatarurl={user.avatar_url} />)

render: ->
cards= @_getAllcards
<div>
<SimpleForm addCard={@_getSpecificCard} />
{cards}
</div>

# second component
SimpleForm= React.createClass

_handleSubmit: (e) ->
e.preventDefault()
textInput= @refs.login
@props.addCard(textInput.value)

render: ->
<form onSubmit={@_handleSubmit}>
<input placeholder="github login" ref="login" />
<button>Show user</button>
</form>

# third component
Card = React.createClass
render: ->
<div>
<h3>{@props.name}</h3>
<img src={@props.avatarurl} width=80 />
</div>

ReactDOM.render(<MainComponent />,document.getElementById("pluralsight"))


// compiled version

$(function() {
var Card, MainComponent, SimpleForm;
MainComponent = React.createClass({displayName: "MainComponent",
getInitialState: function() {
return {
names: []
};
},
_getSpecificCard: function(card_name) {
return $.get("home/users/" + card_name, function(newuser) {
return this.setState({
names: this.state.names.concat([newuser])
});
});
},
_getAllcards: function() {
return this.state.names.map(function(user) {
return React.createElement(Card, {
"key": user.id,
"name": user.login,
"avatarurl": user.avatar_url
});
});
},
render: function() {
var cards;
cards = this._getAllcards;
return React.createElement("div", null, React.createElement(SimpleForm, {
"addCard": this._getSpecificCard
}), cards);
}
});
SimpleForm = React.createClass({displayName: "SimpleForm",
_handleSubmit: function(e) {
var textInput;
e.preventDefault();
textInput = this.refs.login;
return this.props.addCard(textInput.value);
},
render: function() {
return React.createElement("form", {
"onSubmit": this._handleSubmit
}, React.createElement("input", {
"placeholder": "github login",
"ref": "login"
}), React.createElement("button", null, "Show user"));
}
});
Card = React.createClass({displayName: "Card",
render: function() {
return React.createElement("div", null, React.createElement("h3", null, this.props.name), React.createElement("img", {
"src": this.props.avatarurl,
"width": 80
}));
}
});
return ReactDOM.render(React.createElement(MainComponent, null), document.getElementById("pluralsight"));
});

Answer

To ensure that this refers to the component class in the callback, use =>:

$.get "home/users/#{card_name}", (newuser) => @setState names:@state.names.concat([newuser])
                                           ^

Otherwise, it is out of scope when the callback is executed.

Comments