通过具有已知键名的 props 访问数据 react js
2015-06-17
161
刚开始学习 React JS,遇到了一些困难。
我目前有两个组件(可能做错了)。
-
LootBox
- LootTable
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>
)
}
});
Render
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 不是对象(评估“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
]
3个回答
您收到此 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。
Michael Parker
2015-06-17
ajax 调用是否像您发布的那样返回数组?
如果是,您需要执行
this.props.data[0].head.id
Crob
2015-06-17
您的初始渲染(在
componentDidMount
之前)不会有任何数据,因此您的
LootTable
组件将针对空数组进行工作,这是行不通的。
Andrew Ingram
2015-06-17