带有 Google 地图的 ReactJS - 随时显示一条信息 window
ReactJS with Google Maps - displaying one info window at any time
我正在使用 react-google-maps,我能够显示标记和 InfoWindow - 它工作正常,但我只想显示当前活动标记 window。
我正在使用 isOpen 状态来存储当前标记并显示它是否与当前键匹配,但它仍然允许您单击并切换所有标记信息 windows。我怀疑我犯了一个非常简单的错误,但我对 ReactJS 还很陌生。另外,请注意,我发现了非常相似的问题,但 none 帮助我解决了这个问题。
这是我的代码..
constructor(props){
super(props);
this.state = {
isOpen: '',
}
}
handleToggleOpen = (e) => {
this.setState({
isOpen: e
});
console.log(e);
console.log('current state is... ');
console.log(this.state.isOpen);
}
handleToggleClose = () => {
this.setState({
isOpen: null
});
}
render() {
// console.log(this.props.marker.id)
return (
<div>
<Marker
key={this.props.marker.id}
position={{ lat: parseFloat(this.props.marker.acf.locations.lat), lng: parseFloat(this.props.marker.acf.locations.lng)}}
icon={{
url: this.props.icon,
optimized: false,
scaledSize: new google.maps.Size(25, 37),
}}
onClick={() => this.handleToggleOpen(this.props.marker.id)}
audioPlay={this.props.audioPlay} >
{
this.state.isOpen === this.props.marker.id && (
<InfoWindow onCloseClick={this.handleToggleClose}>
<div>
<h3 className="infowindow__title">{this.props.marker.title.rendered} {this.props.marker.acf.title_sub} </h3>
<span onClick={() =>this.refs.componentToDisplay.showPopup()} className="infowindow__link underline">Learn more</span>
</div>
</InfoWindow>)
}
<PlacePopup ref="componentToDisplay" title={this.props.marker.title.rendered} intro={this.props.marker.acf.text} id={this.props.marker.id} subtitle={this.props.marker.acf.title_sub} audio={this.props.marker.acf.file} audioPlay={this.props.audioPlay} >
</PlacePopup>
</Marker>
</div>
)
}
由于每个标记都有自己的状态,因此您必须找到一种方法来连接每个标记组件的每个状态对象。您需要每个标记的状态的原因是,当其中一个标记被单击时,它必须通知所有其他标记有一个标记被单击,因此如果它们的 windows 打开,它们必须立即关闭它。在这种情况下,我建议使用 Redux 解决这个问题(因为你说你对 React 还是新手,我不太确定你是否已经熟悉 Redux,所以如果你熟悉请告诉我评论,我将尝试帮助提供使用 Redux 的解决方案)。我相信,如果没有 Redux 的帮助,你仍然可以设法解决问题,但是将来它可能会变得非常复杂和难以控制。
此外,我认为您的代码中有几处需要先修复。将状态中的 isOpen
设置为布尔值而不是字符串会好得多。因此,您应该对代码进行以下更改:
在你的构造函数中,初始化isOpen
:
this.state = {
isOpen: 假
}
在你的 handleToggleOpen 函数中,不需要传递任何参数,所以你可以删除 e
:
handleToggleOpen = () => {
this.setState({
isOpen: !this.state.isOpen
});
}
这基本上就是切换,因此您也可以删除 handleToggleClose
函数(因为 handleToggleOpen
处理打开和关闭),然后将其替换为 handleToggleOpen
渲染函数。
- 现在你只需要改变
this.state.isOpen === this.props.marker.id &&
简单地
this.state.isOpen &&
那么它应该可以正常工作,而不需要每次都比较每个标记的 id。
我正在使用 react-google-maps,我能够显示标记和 InfoWindow - 它工作正常,但我只想显示当前活动标记 window。
我正在使用 isOpen 状态来存储当前标记并显示它是否与当前键匹配,但它仍然允许您单击并切换所有标记信息 windows。我怀疑我犯了一个非常简单的错误,但我对 ReactJS 还很陌生。另外,请注意,我发现了非常相似的问题,但 none 帮助我解决了这个问题。
这是我的代码..
constructor(props){
super(props);
this.state = {
isOpen: '',
}
}
handleToggleOpen = (e) => {
this.setState({
isOpen: e
});
console.log(e);
console.log('current state is... ');
console.log(this.state.isOpen);
}
handleToggleClose = () => {
this.setState({
isOpen: null
});
}
render() {
// console.log(this.props.marker.id)
return (
<div>
<Marker
key={this.props.marker.id}
position={{ lat: parseFloat(this.props.marker.acf.locations.lat), lng: parseFloat(this.props.marker.acf.locations.lng)}}
icon={{
url: this.props.icon,
optimized: false,
scaledSize: new google.maps.Size(25, 37),
}}
onClick={() => this.handleToggleOpen(this.props.marker.id)}
audioPlay={this.props.audioPlay} >
{
this.state.isOpen === this.props.marker.id && (
<InfoWindow onCloseClick={this.handleToggleClose}>
<div>
<h3 className="infowindow__title">{this.props.marker.title.rendered} {this.props.marker.acf.title_sub} </h3>
<span onClick={() =>this.refs.componentToDisplay.showPopup()} className="infowindow__link underline">Learn more</span>
</div>
</InfoWindow>)
}
<PlacePopup ref="componentToDisplay" title={this.props.marker.title.rendered} intro={this.props.marker.acf.text} id={this.props.marker.id} subtitle={this.props.marker.acf.title_sub} audio={this.props.marker.acf.file} audioPlay={this.props.audioPlay} >
</PlacePopup>
</Marker>
</div>
)
}
由于每个标记都有自己的状态,因此您必须找到一种方法来连接每个标记组件的每个状态对象。您需要每个标记的状态的原因是,当其中一个标记被单击时,它必须通知所有其他标记有一个标记被单击,因此如果它们的 windows 打开,它们必须立即关闭它。在这种情况下,我建议使用 Redux 解决这个问题(因为你说你对 React 还是新手,我不太确定你是否已经熟悉 Redux,所以如果你熟悉请告诉我评论,我将尝试帮助提供使用 Redux 的解决方案)。我相信,如果没有 Redux 的帮助,你仍然可以设法解决问题,但是将来它可能会变得非常复杂和难以控制。
此外,我认为您的代码中有几处需要先修复。将状态中的 isOpen
设置为布尔值而不是字符串会好得多。因此,您应该对代码进行以下更改:
在你的构造函数中,初始化
isOpen
:this.state = { isOpen: 假 }
在你的 handleToggleOpen 函数中,不需要传递任何参数,所以你可以删除
e
:handleToggleOpen = () => { this.setState({ isOpen: !this.state.isOpen }); }
这基本上就是切换,因此您也可以删除 handleToggleClose
函数(因为 handleToggleOpen
处理打开和关闭),然后将其替换为 handleToggleOpen
渲染函数。
- 现在你只需要改变
this.state.isOpen === this.props.marker.id &&
简单地
this.state.isOpen &&
那么它应该可以正常工作,而不需要每次都比较每个标记的 id。