从 MapView 组件访问 ref 属性以供外部函数使用

Posted

技术标签:

【中文标题】从 MapView 组件访问 ref 属性以供外部函数使用【英文标题】:Access ref prop from MapView component for use by outside function 【发布时间】:2019-12-05 21:25:33 【问题描述】:

有没有办法从外部函数访问 MapView 组件的 ref 属性?

基本上,我有:

    具有渲染方法的主组件将调用(<MyMap />)

    <MyMap /> 是 MapView 组件的导出函数。在 MapView 组件中,我创建了一个引用 (ref=map=>(mapRef=map),并希望将该引用传递给生成我的标记 (<PinData /> 的函数。

    <PinData />,我想使用 onPress 事件 标记以放大并使用 MapView.animateToRegion 方法。

我不断得到 undefined is not an object(评估 'mapRef.animateToRegion')。

为了呈现 MapView 和 Markers 组件,我是否必须创建组件类(而不是使用导出的函数)才能使地图引用工作?

例如: 主类组件:

render()
     return(
          <View>
             <MyMap region=this.state.region 
                    pinData=this.state.pinsData 
                    myPins=this.state.myPins
                    mapRef=this._mapRef />
          </View>
)

MyMap 函数呈现我的 MapView 组件。

export const MyMap= ( region, pinsData, myPins) => 

  return (
    <View style=styles.container>
      <MapView
        provider=PROVIDER_GOOGLE
        ref=map => (mapRef = map)
        style=styles.userMap
        region=region
      >
        <PinData pinsData=pinsData myPins=myPins />
      </MapView>
    </View>
  );

用于在我的地图上生成标记的 PinData 函数。

export const PinData = ( pinsData, myPins, mapRef ) => 
  return pinsData.map((pin, index) => (
    <Marker
      key=index
      ref=ref => (markers[index] = ref)
      coordinate=
        longitude: pin.coordinates.lng,
        latitude: pin.coordinates.lat
      
      onPress=focusMarker(mapRef, pin, index)
    />
  ));
;

onPress 函数,该函数将使用与 MapView 对象关联的 animateToRegion 方法放大其中一个图钉。

focusMarker = (mapRef, location, index) => 
  mapRef.animateToRegion(
    latitude: location.coordinates.lat,
    longitude: location.coordinates.lng,
    latitudeDelta: 0.005,
    longitudeDelta: 0.005
  );
;

【问题讨论】:

【参考方案1】:

您可以将onPress 属性传递给PinData

export const MyMap= ( region, pinsData, myPins) => 
    const mapRef = useRef();

  focusMarker = (location) => 
    mapRef.current.animateToRegion(
      latitude: location.coordinates.lat,
      longitude: location.coordinates.lng,
      latitudeDelta: 0.005,
      longitudeDelta: 0.005
    );
  ;

  return (
    <View style=styles.container>
      <MapView
        provider=PROVIDER_GOOGLE
        ref=mapRef
        style=styles.userMap
        region=region
      >
        <PinData pinsData=pinsData myPins=myPins onPress=focusMarker/>
      </MapView>
   </View>
);



export const PinData = ( pinsData, myPins, onPress ) => 
  return pinsData.map((pin, index) => (
    <Marker
      key=index
      ref=ref => (markers[index] = ref)
      coordinate=
        longitude: pin.coordinates.lng,
        latitude: pin.coordinates.lat
      
      onPress=() => onPress(pin)
    />
  ));
;

【讨论】:

这非常有效。快速提问,只是为了让我理解它是如何工作的逻辑。您可以通过调用 useRef() 创建 MapView 组件的引用。 onPress 部分是如何工作的?您引用了一个名为 onPress 的道具并将其链接到 focusMarker 函数。然后,在 PinData 函数中,您为 onPress Marker prop 调用一个匿名函数,该函数指向 onPress(接收 pin)作为参数。这个 onPress 是如何工作的?在 PinData 函数中 focusMarker 是如何引用 pin 的?【参考方案2】:

感谢 Tuan 的回答,我想通了。上面的代码有效。我之前不理解的是 onPress 是如何工作的。基本上,据我的理解,逻辑如下:

在 MyMap 函数中,我们定义了 focusMarker 函数。

然后在调用的 onPress 中创建一个 prop 并将其设置为等于 focusMarker 函数。

在 PinData 函数中,我们现在将这个 prop(onPress) in 作为参数,并将 Marker 组件中的 onPress prop 设置为一个匿名函数,该函数将执行带有 pin 参数的 focusMarker 函数。在这个函数中,作为导出函数的参数传入的onPress实际上是focusMarker函数本身,我们使用pin参数调用它。希望这对任何可以利用它的人都有意义。再次感谢团。欣赏它。我有一段时间被这个问题难住了。

【讨论】:

以上是关于从 MapView 组件访问 ref 属性以供外部函数使用的主要内容,如果未能解决你的问题,请参考以下文章

React组件三大属性props state refs以及组件的生命周期

React组件三大属性props state refs以及组件的生命周期

React组件三大属性props state refs以及组件的生命周期

如何获取组件数据?如何从外部访问组件?

VUE从入门到入坑—06. 父子组件通信 / 几种常用的第三方组件库

类型“MapView”上不存在属性“地图”