问题
I am trying to create a simple a TODO list app in ReactJS. My basics of React are not very clear so I am stuck here.
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>React TODO</title>
<script src="../../build/react.js"></script>
<script src="../../build/react-dom.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.24/browser.min.js"></script>
</head>
<body>
<div id="example"></div>
<script type="text/babel" lang="ja">
var TodoList = React.createClass({
Checked: function(e) {
alert("Checked");
},
render: function() {
var createItem = function(item) {
return <li key={item.id}>{item.text}<input type="checkbox" onChange={this.Checked} /></li>;
};
return <ul>{this.props.items.map(createItem)}</ul>;
}
});
var TodoApp = React.createClass({
getInitialState: function() {
return {items: [], text: ''};
},
onButtonClick: function(e) {
this.setState({text: e.target.value});
},
handleSubmit: function(e) {
e.preventDefault();
var nextItems = this.state.items.concat([{text: this.state.text, id: Date.now()}]);
var nextText = '';
this.setState({items: nextItems, text: nextText});
},
render: function() {
return (
<div>
<h3>TODO</h3>
<TodoList items={this.state.items} />
<form onSubmit={this.handleSubmit}>
<input onChange={this.onButtonClick} value={this.state.text} />
<button>{'Add #' + (this.state.items.length + 1)}</button>
</form>
</div>
);
}
});
ReactDOM.render(<TodoApp />, document.getElementById('example'));
</script>
</body>
</html>
With every list generated, a checkbox is assigned to it . Code works fine without onChange event to Checkbox. But when "Checked" function is assigned to it, error is generated.
Uncaught TypeError: Cannot read property 'Checked' of undefined
Thanks in advance
回答1:
You need set this for .map (you can do that through second argument in .map)
return <ul>{this.props.items.map(createItem, this)}</ul>;
Example
because now in createItem this refers to global (in browsers it will be window) score (or if you use strict mode this will be undefined)
as you use babel you also can use arrow functions
var createItem = (item) => {
return <li key={item.id}>
{item.text}<input type="checkbox" onChange={this.Checked} />
</li>;
};
return <ul>{this.props.items.map(createItem)}</ul>;
Example
回答2:
you can go with Alex Solution but you can also achieve the same thing by changing only two place like
var that=this;
var createItem = function(item) {
return <li key={item.id}>{item.text}<input type="checkbox" onChange={that.Checked} /></li>;
};
return <ul>{this.props.items.map(createItem)}</ul>;
回答3:
Make createItem a method of TodoList class. The "this" reference is not being resolved as right now its a local function of render method. On a side note, React follows camel casing for handlers. Please rename the Clicked method to onChange, onChecked or onCheckClicked.
来源:https://stackoverflow.com/questions/34629343/uncaught-typeerror-cannot-read-property-checked-of-undefined-reactjs