刚开始学习React JS,我已经打了一个砖墙。
我目前有两个组件(可能是错误的方法)。
LootBox通过ajax调用json文件,LootTable需要访问这些数据。
这是我目前的代码。
var LootBox = React.createClass({
loadLootFromServer: function() {
$.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)
});
},
getInitialState: function() {
return {data: []};
},
componentDidMount: function() {
this.loadLootFromServer();
},
render: function () {
return (
<LootTable data={this.state.data} />
)
}
});
LootTable
var LootTable = React.createClass({
render: function () {
return (
<div className="table-responsive">
<table className="table table-bordered table-hover">
<tr>
<th>Head <span className="glyphicon glyphicon-th-list pull-right"></span></th>
<th>Neck <span className="glyphicon glyphicon-th-list pull-right"></span></th>
</tr>
<tr>
<td>{this.props.data.head.id}</td>
<td>{this.props.data.neck.id}</td>
</tr>
<tr>
<th>Shoulder <span className="glyphicon glyphicon-th-list pull-right"></span></th>
<th>Chest <span className="glyphicon glyphicon-th-list pull-right"></span></th>
</tr>
<tr>
<td></td>
<td></td>
</tr>
<tr>
<th>Waist <span className="glyphicon glyphicon-th-list pull-right"></span></th>
<th>Legs <span className="glyphicon glyphicon-th-list pull-right"></span></th>
</tr>
<tr>
<td></td>
<td></td>
</tr>
<tr>
<th>Feet <span className="glyphicon glyphicon-th-list pull-right"></span></th>
<th>Wrist <span className="glyphicon glyphicon-th-list pull-right"></span></th>
</tr>
<tr>
<td></td>
<td></td>
</tr>
<tr>
<th>Gloves <span className="glyphicon glyphicon-th-list pull-right"></span></th>
<th>Back <span className="glyphicon glyphicon-th-list pull-right"></span></th>
</tr>
<tr>
<td></td>
<td></td>
</tr>
<tr>
<th>Ring 1 <span className="glyphicon glyphicon-th-list pull-right"></span></th>
<th>Ring 2 <span className="glyphicon glyphicon-th-list pull-right"></span></th>
</tr>
<tr>
<td></td>
<td></td>
</tr>
<tr>
<th>Trinket 1 <span className="glyphicon glyphicon-th-list pull-right"></span></th>
<th>Trinket 2 <span className="glyphicon glyphicon-th-list pull-right"></span></th>
</tr>
<tr>
<td></td>
<td></td>
</tr>
<tr>
<th>Main Hand <span className="glyphicon glyphicon-th-list pull-right"></span></th>
<th>Off Hand <span className="glyphicon glyphicon-th-list pull-right"></span></th>
</tr>
<tr>
<td></td>
<td></td>
</tr>
</table>
</div>
)
}
});
渲染
React.render(
<LootBox url="http://127.0.0.1:3001/loot.json" />,
document.getElementById('content')
);
JSON
[
{
"main_hand": {
"id": 113937,
"bonus": "449"
},
"off_hand": {
"id": 113960,
"bonus": "449"
},
"head": {
"id": 119321,
"bonus": "449"
},
"neck": {
"id": 113890,
"bonus": "449"
},
"shoulders": {
"id": 119322,
"bonus": "449"
},
"back": {
"id": 113878,
"bonus": "449"
},
"chest": {
"id": null,
"bonus": "None"
},
"wrist": {
"id": 113935,
"bonus": "449"
},
"hands": {
"id": 119319,
"bonus": "449"
},
"waist": {
"id": 113964,
"bonus": "449"
},
"legs": {
"id": 119320,
"bonus": "449"
},
"feet": {
"id": 113895,
"bonus": "449"
},
"finger1": {
"id": 113901,
"bonus": "449"
},
"finger2": {
"id": null,
"bonus": "None"
},
"trinket1": {
"id": 113889,
"bonus": "449"
},
"trinket2": {
"id": 113986,
"bonus": "449"
}
}
]
我不完全确定我做错了什么,因为在尝试访问LootBox上的道具时(例如this.props.data.head.id),我得到了TypeError: undefined is not an object (evaluating 'this.props.data.head.id')
有人有什么理论吗?
编辑:将console.log添加到成功函数后,我将返回此内容。
[Log] [ (loot, line 10)
Object
back: Object
bonus: "449"
id: 113878
__proto__: Object
chest: Object
feet: Object
finger1: Object
finger2: Object
hands: Object
head: Object
legs: Object
main_hand: Object
neck: Object
off_hand: Object
shoulders: Object
trinket1: Object
trinket2: Object
waist: Object
wrist: Object
__proto__: Object
]
答案 0 :(得分:1)
你得到这个TypeError的原因是因为你在LootBox组件上的data
的初始状态是一个空数组。这会在初始渲染时传递给LootTable。这意味着LootTable的初始渲染上的this.props.data
是一个空数组,并且它试图访问空数组上的head
键并且无法执行此操作,从而导致TypeError。
可能的解决方案是在尝试访问其密钥之前检查空数组。像这样:
var LootTable = React.createClass({
render: function () {
var headID = this.props.data.head.id == null ? "Default value" : this.props.data.head.id;
var neckID = this.props.data.neck.is == null ? "Default value" : this.props.data.neck.id;
return (
<snip>
)
}
});
然后你只需使用创建的变量而不是JSX中的props。
答案 1 :(得分:-1)
ajax调用是否返回了您发布的数组?
如果是这样,您需要执行this.props.data[0].head.id
答案 2 :(得分:-1)
您的初始渲染(在componentDidMount
之前)将不会有任何数据,因此您的LootTable
组件将针对空数组工作,这将无效。