我创建了一个用React.js动态加载其内容的网页。我从REST api调用中检索对象数组,然后将它们提供给表。我遇到的问题是array.map中的onClick赋值不会触发指定的函数。
我认为这是[ 此 ]上下文问题,但我不确定如何解决它。 array.map中的[ this ]与array.map之外的[ 此 ]不同如console.log所示。
我创建了两个独立的html文件进行演示。第一个包含静态创建的对象,该对象正确调用onClick函数:
https://jsfiddle.net/m1vugyd9/
第二次尝试从一组对象动态加载,但不起作用:
https://jsfiddle.net/avmbdxte/
我不知道这些链接有多长时间处于活动状态,所以如果它们不起作用,我还会在下面包含实际的html。差异在评论中略显突出。
静态 - 工作:
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<style>
table {
text-align: center;
}
</style>
</head>
<body>
<div id="reactDiv"></div>
<script src="https://fb.me/react-0.14.3.min.js"></script>
<script src="https://fb.me/JSXTransformer-0.13.3.js"></script>
<script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
<script type="text/jsx">
var FMap = React.createClass({
render: function() {
return (
<tr>
<td>{this.props.sTable}</td>
<td>{this.props.sField}</td>
<td>{this.props.dTable}</td>
<td>{this.props.dField}</td>
<td><a href="#" onClick={this.props.mapCountClick}>{this.props.mapCount}</a></td>
</tr>
);
}
});
var Main = React.createClass({
getInitialState: function () {
return { mapData: [] };
},
editMaps: function() {
alert("Clicked on map editor");
},
render: function () {
var maps = [
{
mapID: 1,
sourceT: "sT1",
sourceF: "sF1",
destT: "dT1",
destF: "dF1",
mapCount: 6
},
{
mapID: 2,
sourceT: "sT1",
sourceF: "sF2",
destT: "dT1",
destF: "dF2",
mapCount: 2
}
];
/////////////////////////////////////////////////////
// this is the static part that's different from the dynamic part
var fMaps =
<FMap key="1"
sTable="sT1"
sField="sF1"
dTable="dT1"
dField="dF1"
mapCount="6"
mapCountClick={this.editMaps} />;
// end of difference
/////////////////////////////////////////////////////
return (
<table width="100%">
<thead>
<tr>
<th>SourceT</th>
<th>SourceF</th>
<th>DestT</th>
<th>DestF</th>
<th>MapCount</th>
</tr>
</thead>
<tbody>
{fMaps}
</tbody>
</table>
);
}
});
React.render(<Main />, document.getElementById("reactDiv"));
</script>
</body>
</html>
动态 - 不起作用:
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<style>
table {
text-align: center;
}
</style>
</head>
<body>
<div id="reactDiv"></div>
<script src="https://fb.me/react-0.14.3.min.js"></script>
<script src="https://fb.me/JSXTransformer-0.13.3.js"></script>
<script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
<script type="text/jsx">
var FMap = React.createClass({
render: function() {
return (
<tr>
<td>{this.props.sTable}</td>
<td>{this.props.sField}</td>
<td>{this.props.dTable}</td>
<td>{this.props.dField}</td>
<td><a href="#" onClick={this.props.mapCountClick}>{this.props.mapCount}</a></td>
</tr>
);
}
});
var Main = React.createClass({
getInitialState: function () {
return { mapData: [] };
},
editMaps: function() {
alert("Clicked on map editor");
},
render: function () {
var maps = [
{
mapID: 1,
sourceT: "sT1",
sourceF: "sF1",
destT: "dT1",
destF: "dF1",
mapCount: 6
},
{
mapID: 2,
sourceT: "sT1",
sourceF: "sF2",
destT: "dT1",
destF: "dF2",
mapCount: 2
}
];
/////////////////////////////////////////////////////
// this is the part that doesn't work
var fMaps = maps.map(function (map) {
var component = this;
return (
<FMap key={map.mapID}
sTable={map.sourceT}
sField={map.sourceF}
dTable={map.destT}
dField={map.destF}
mapCount={map.mapCount}
mapCountClick={this.editMaps} />
);
});
// end
/////////////////////////////////////////////////////
return (
<table width="100%">
<thead>
<tr>
<th>SourceT</th>
<th>SourceF</th>
<th>DestT</th>
<th>DestF</th>
<th>MapCount</th>
</tr>
</thead>
<tbody>
{fMaps}
</tbody>
</table>
);
}
});
React.render(<Main />, document.getElementById("reactDiv"));
</script>
</body>
</html>
工作示例(感谢pvg!):
https://jsfiddle.net/qLp9uuq3/
另一个工作示例(感谢Matthew Herbst!):
答案 0 :(得分:7)
在代码的动态部分:Map()
默认情况下不会从组件中获取this
的值,因此您需要绑定它:
var fMaps = maps.map(function (map) {
return (
<FMap key={map.mapID}
sTable={map.sourceT}
sField={map.sourceF}
dTable={map.destT}
dField={map.destF}
mapCount={map.mapCount}
mapCountClick={this.editMaps} />
);
}.bind(this));
如果您使用了ES6箭头功能,this
将被词汇继承,您就不会遇到此问题:
var fMaps = maps.map((map) => {
return (
<FMap key={map.mapID}
sTable={map.sourceT}
sField={map.sourceF}
dTable={map.destT}
dField={map.destF}
mapCount={map.mapCount}
mapCountClick={this.editMaps} />
);
});
考虑到您可能已经使用Babel或其他工具进行JSX转换,可能也值得研究ES6转换。开始学习未来的好方法!