将数据传回父组件的ReactJS组件无法工作
ReactJS component passing data back to parent component not working
我正在开发一个ReactJS组件,该组件通过Google Maps Javascript API呈现Google地图。在地图上,我动态地放置标记,显示不同的经销商位置。现在,模拟数据来自一组具有不同信息的分配器,并通过循环进行迭代。当点击一个标记时,我会在信息窗口中显示分销商的详细信息。现在,在这个信息窗口中,我有一个按钮,允许客户选择这个分销商。
GoogleMap组件归ChooseDistributor组件所有。单击按钮后,我希望通过回调函数将ID(现在是一个具有分发服务器名称的字符串)发送回ChooseDistributor组件。
问题是,当我点击按钮时,我得到了一个Uncaught TypeError: Cannot read property 'callbackParent' of undefined
。这可能是一个范围问题,因为当我在循环中时,this
没有引用GoogleMap组件本身(?)。
然后,我尝试在循环之外创建一个变量callbackParent
,该变量包含应该链接回ChooseDistributor组件中的接收函数的this.props.callbackParent
。然后我在按钮onclick上调用这个变量。这也不起作用,因为我正在获得Uncaught ReferenceError: callbackParent is not defined
。
如果有人能解决这个问题,我将不胜感激。我是遗漏了什么,还是一个明显的语法错误?提前谢谢。
下面是我的代码。
选择分销商组件
var ChooseDistributor = React.createClass({
getSelectedDistributor: function(company){
alert(company);
},
render: function(){
return(
<div>
<Header headerClass="title" title="Choose distributor"/>
<div className="fillViewPort">
<GoogleMap enableIwSelectButton={true} callbackParent={this.getSelectedDistributor}/>
</div>
<NavBar />
</div>
);
}
})
module.exports = ChooseDistributor;
GoogleMap组件:
var GoogleMap = React.createClass({
getInitialState: function(){
return {
// LOCATIONS STATE SHOULD GET DATA FROM STORE
locations: [
// ARRAY VALUES: [0]=LAT, [1]=LNG, [2]=COMPANY, [3]=ADDRESS, [4]=CITY, [5]=WEBSITE, [6]=PHONE, [7]=EMAIL
[55.628353, 12.388910, 'Distributor One', 'First street 11', '1111 Copenhagen', 'www.company.com', '+4512345678', 'distributor@company.dk'],
[55.623321, 12.388438, 'Distributor Two', 'Second street 22', '2222 Copenhagen', 'www.company.com', '+4512345678', 'distributor@company.dk'],
[55.670710, 12.389256, 'Distributor Three', 'Third street 33', '3333 Copenhagen', 'www.company.com', '+4512345678', 'distributor@company.dk'],
[55.581179, 12.295583, 'Distributor Four', 'Fourth street 44', '4444 Copenhagen', 'www.company.com', '+4512345678', 'distributor@company.dk'],
[55.647296, 12.284211, 'Distributor Five', 'Fifth street 55', '5555 Copenhagen', 'www.company.com', '+4512345678', 'distributor@company.dk']
]
}
},
componentDidMount: function(){
var locations = this.state.locations;
var enableIwSelectButton = this.props.enableIwSelectButton;
var callbackParent = this.props.callbackParent;
var map = new google.maps.Map(document.getElementById('googleMap'), {
zoom: 11,
center: new google.maps.LatLng(locations[0][0], locations[0][1]), // CENTER PROPERTY SHOULD GET COORDINATES OF THE DEVICE CURRENT LOCATION IF PERMITTED.
mapTypeControlOptions: {
mapTypeIds: [google.maps.MapTypeId.ROADMAP]
},
mapTypeId: google.maps.MapTypeId.ROADMAP,
disableDefaultUI: true
});
var infoWindow = new google.maps.InfoWindow();
var marker, i;
// PLACE MARKER ON MAP FOR EACH DISTRIBUTOR POSITION IN ARRAY.
for (i = 0; i < locations.length; i++) {
marker = new google.maps.Marker({
position: new google.maps.LatLng(locations[i][0], locations[i][1]),
map: map
});
// ADD INFOWINDOW WITH DISTRIBUTOR DETAILS TO EACH MARKER.
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infoWindow.setContent('<p class="iwTitle">' + locations[i][2] + '</p>'+
'<p class="iwText">' + locations[i][3] + '<br>' +
locations[i][4] + '<br>' +
'<a href="http://' + locations[i][5] + '">' + locations[i][5] + '</a></p>' +
'<p class="iwText"><i class="fa fa-phone iwIcons"></i>' + locations[i][6] + '<br>' +
'<i class="fa fa-envelope iwIcons"></i><a href="mailto:"' + locations[i][7] + '>' + locations[i][7] + '</a></p>' +
(enableIwSelectButton ? '<button type="button" class="iwButton" onclick={this.props.callbackParent(locations[i][3])}><p>Select Distributor</p></button>' : ''));
infoWindow.open(map, marker);
}
})(marker, i));
}
},
render: function(){
return(
<div id="googleMap" className="size-100-pct" />
);
}
})
module.exports = GoogleMap;
更新:感谢@Radio,我的问题解决了。解决方案是给每个按钮一个Id,然后根据该Id获取按钮,并向其添加一个事件侦听器,如下所示:
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infoWindow.setContent('<p class="iwTitle">' + locations[i][2] + '</p>'+
'<p class="iwText">' + locations[i][3] + '<br>' +
locations[i][4] + '<br>' +
'<a href="http://' + locations[i][5] + '">' + locations[i][5] + '</a></p>' +
'<p class="iwText"><i class="fa fa-phone iwIcons"></i>' + locations[i][6] + '<br>' +
'<i class="fa fa-envelope iwIcons"></i><a href="mailto:"' + locations[i][7] + '>' + locations[i][7] + '</a></p>' +
(enableIwSelectButton ? '<button type="button" id="btnSelect' + i + '" class="iwButton"><p>Select Distributor</p></button>' : ''));
infoWindow.open(map, marker);
var el = document.getElementById("btnSelect" + i);
el.addEventListener("click", function(){callbackParent(locations[i][2])});
}
})(marker, i));
InfoWindow中的按钮不是React组件。它是原始html,可能由setContent
解析。因此,按钮的"onclick"属性将尝试在全局命名空间中执行一个函数。它不知道它是如何创建的,而且callbackParent
、this.props.callbackParent
和locations[i][3]
都不在供其引用的全局命名空间中。
您可以在componentDidMount
中使用常规的DOM操作来添加事件侦听器。
infoWindow.setContent(... '<button type="button" class="iwButton"><p>Select Distributor</p></button>' : ''));
infoWindow.open(map, marker);
var el = document.getElementsByClassName("iwButton");
el.addEventListener("click", function() { callbackParent(locations[i][3]) });
callback
方法内部的'this
'指回调本身。因此,您不能访问回调函数内部的"this
"来引用外部作用域。
尝试ES6语法:
myFn:()=>{
this.props.any();
}
或者,
var self = this.
myFn:function(){
self.props.any();
}
- 拨打'父亲'函数形式a'儿童'ReactJS中的组件
- 如何更改reactjs中外部/独立组件的状态或属性
- 如何在ReactJs中渲染子组件时重新加载子组件的数据
- 在reactjs组件中预加载数据
- ReactJS-在加载时渲染顶级组件
- 组件未使用ReactJS和React Router进行渲染
- ReactJS中未定义组件
- 我不知道如何正确地将REST响应对象传递给ReactJS子组件
- reactjs-redux,是否可以有一个由2个组件使用的状态
- ReactJS组件中显示的视频未更新
- 组件中的ReactJS意外令牌
- 当写入“;函数“;在ReactJS组件中
- 将可重复使用的组件与ReactJs和Flux一起用于多个存储
- ReactJS中的子-父组件通信
- 如何在reactjs中动态加载组件
- 从子窗体组件ReactJS中获取道具
- 可以't重新渲染子组件reactjs
- React 在点击时渲染其他组件.ReactJS中的最优模式
- 正在更新不工作的组件ReactJs
- 父组件多次重新渲染子组件ReactJS