React-google-maps infowindow:`React.Children.only` 期望只接收一个 React 元素子节点。

5
我试图在单击特定标记时打开信息窗口,但似乎点击任何一个标记都会打开所有标记的信息窗口,并显示以下错误: React.Children.only expected to receive a single React element child. 以下是我目前的代码:
import React, { Component } from 'react';
import {  GoogleMap, Marker, withGoogleMap, withScriptjs, InfoWindow } from 'react-google-maps'

class Map extends Component {
  state = {
    isOpen: false
  }

  handleMarkerClick = () => {
    this.setState({ isOpen: true})
  }

  render() {
    return(
    <div>
      <GoogleMap
        defaultZoom={13}
        defaultCenter={{ lat: -22.9034778, lng: -43.1264636 }}
      >{this.props.markers.map((marker, index) =>(
        <Marker
          key={index}
          position={marker.location}
          onClick={this.handleMarkerClick}
         >{this.state.isOpen && <InfoWindow onCloseClick={this.handleMarkerClick}/>}
       </Marker>
      ))}
      </GoogleMap>
    </div>
    )
  }
}

export default withScriptjs(withGoogleMap(Map))

编辑开始

我做了一些更改来解决评论问题,但目前还没有生效。你能给我一些提示吗?由于我对顶部组件进行了一些更改,因此我将在此处粘贴它:

import React, { Component } from 'react';
import Map from './Map.js'
import List from './List.js'
import escapeRegExp from 'escape-string-regexp'
import sortBy from 'sort-by'

class App extends Component {
  state ={
    locations:[
      {
        name: "Paróquia Nossa Senhora das Dores do Ingá",
        location: {
          lat: -22.9038875,
          lng: -43.1252873
        },
        isOpen:false,
      },
      {
        name: "Museu de Arte Contemporanea de Niteroi",
        location: {
          lat: -22.9078182,
          lng: -43.1262919
        },
        isOpen:false,
      },
      {
        name: "UFF - Faculdade de Direito",
        location: {
          lat: -22.9038469,
          lng: -43.126024
        },
        isOpen:false,
      },
      {
        name: "Ponte Rio-Niterói",
        location: {
          lat: -22.8701,
          lng: -43.167
        },
        isOpen:false,
      },
      {
        name: "Fundação Oscar Niemeyer",
        location: {
          lat: -22.888533927137285,
          lng: -43.12815992250511
        },
        isOpen:false,
      },
      {
        name: "Campo de São Bento",
        location: {
          lat: -22.905279,
          lng: -43.107759
        },
        isOpen:false,
      }
    ],
    query:''
  }

  onToggleOpen = (location) => {
    this.setState({ isOpen: !this.isOpen })
  }

  updateQuery = (query) => {
    this.setState({ query: query.trim() })
    console.log(query)
  }

  componentDidMount() {}
  render() {
    const { query, locations } = this.state

    let filteredMarkers
    if(query) {
      const match = new RegExp(escapeRegExp(query), 'i')
      filteredMarkers = locations.filter((location) => match.test(location.name))
    }else {
      filteredMarkers = locations
    }

    filteredMarkers.sort(sortBy('name'))

    return (
      <div className="App">
        <div style={{height:`5vh`}}>
          <input
            type='text'
            placeholder='Search locations'
            value={query}
            onChange={(event) => this.updateQuery(event.target.value)}
          />
        </div>
        <List
          markers={filteredMarkers}
        />
        <Map
          onToggle={this.onToggleOpen}
          googleMapURL="https://maps.googleapis.com/maps/api/js?&key=AIzaSyAiqO5W1p5FAFf8RZD11PGigUXSlmVHguQ&v=3"
          loadingElement={<div style={{ height: `100%` }} />}
          containerElement={<div style={{ height: `80vh` }} />}
          mapElement={<div style={{ height: `100%` }} />}
          className="Map"
          markers={filteredMarkers}
        />
      </div>
    );
  }
}

export default App;

Map.js

import React, { Component } from 'react';
import {  GoogleMap, Marker, withGoogleMap, withScriptjs, InfoWindow } from 'react-google-maps'

class Map extends Component {
  render() {
    return(
    <div>
      <GoogleMap
        defaultZoom={13}
        defaultCenter={{ lat: -22.9034778, lng: -43.1264636 }}
      >{this.props.markers.map((marker, index) =>(
        <Marker
          key={index}
          position={marker.location}
          onClick={() => this.props.onToggle(marker)}
         >{marker.isOpen && <InfoWindow onCloseClick={this.ontoggleOpen}>Hello</InfoWindow>}
       </Marker>
      ))}
      </GoogleMap>
    </div>
    )
  }
}

export default withScriptjs(withGoogleMap(Map))

在你的“Map”状态中,你有一个单一的属性,你检查并显示所有信息窗口的“InfoWindow”。因此,如果你点击一个标记,所有的信息窗口都会显示。你应该跟踪哪个标记被点击了,然后输出与相同“index”的标记的信息窗口。 - Anton Kastritskiy
你能分享一个 props.markers 的例子吗?这会帮助我制作一个可行的示例。 - Anton Kastritskiy
props.markers是状态中的位置数组,其中包含以下位置之一: { name: "Paróquia Nossa Senhora das Dores do Ingá", location: { lat: -22.9038875, lng: -43.1252873 }, isOpen:false, } - Daniel Campos
我再折腾了一下,发现点击处理程序是有效的,只是无法使用onToggleOpen函数设置状态,所以我认为问题就出在这里。 - Daniel Campos
让我们在聊天中继续这个讨论 - Daniel Campos
显示剩余2条评论
1个回答

16

我遇到的问题是:React.Children.only期望只接收单个React元素子节点。由于我没有在infowindow中设置一个div,所以只需添加它就可以解决这个特定的问题。

以下是之前的代码:

<InfoWindow onCloseClick={this.handleMarkerClick}/>

以下是应该的代码: <InfoWindow onCloseClick={()=>this.props.onToggle(marker)}><div>你好</div></InfoWindow>

或者类似这样的代码。


1
为这个修复如此简单而感到后悔。 - Dylan Pierce

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接