繁体   English   中英

有没有办法改变 react-native-maps<marker coordinate="{coordinate}" /> API坐标没有重新渲染?

[英]Is there a way to change react-native-maps <Marker coordinate={coordinate} /> API coordinate without re-rendering?

参考: 如何在不重新渲染地图视图的情况下更新标记 position? 反应本机地图

我的目标是防止在用户拖动 map 同时更改市场坐标时重新渲染。 目前的解决方案是使用useState hook。 但它导致组件重新渲染,从而导致应用程序延迟。

我试过使用let variable但它不会移动marker

tl:dr Screen.js

import React from 'react';
import {StyleSheet, View} from 'react-native';
import MapView, {Marker, PROVIDER_GOOGLE} from 'react-native-maps';

const styles = StyleSheet.create({
  container: {
    ...StyleSheet.absoluteFillObject,
    height: 400,
    width: 400,
    justifyContent: 'flex-end',
    alignItems: 'center',
  },
  map: {
    ...StyleSheet.absoluteFillObject,
  },
});

带有 useState 的 Screen.js(昂贵的重新渲染)

export default function GoSendDestinationDetails() {
  const [coordinate, setCoordinate] = React.useState({
    latitude: -6.1754,
    longitude: 106.8272,
    latitudeDelta: 0.015,
    longitudeDelta: 0.0121,
  });
  const handleRegionChange = (region) => {
    setCoordinate(region);
    console.log(region);
  };

  console.log('re-render');

  return (
    <View style={styles.container}>
      <MapView
        provider={PROVIDER_GOOGLE} // remove if not using Google Maps
        style={styles.map}
        initialRegion={coordinate}
        onRegionChange={handleRegionChange}>
        <MarkerMemo />
      </MapView>
    </View>
  );
}

我试过的:

带有 let 变量的 Screen.js

export default function GoSendDestinationDetails() {
  let coordinate = {
    latitude: -6.1754,
    longitude: 106.8272,
    latitudeDelta: 0.015,
    longitudeDelta: 0.0121,
  };
  const handleRegionChange = (region) => {
    coordinate = region;
    console.log(region);
  };

  // this does not update the marker when coordinate changes
  const MarkerMemo = React.memo(() => <Marker coordinate={coordinate} />)

  console.log('re-render');
  return (
    <View style={styles.container}>
      <MapView
        provider={PROVIDER_GOOGLE} // remove if not using Google Maps
        style={styles.map}
        initialRegion={coordinate}
        onRegionChange={handleRegionChange}>
        <MarkerMemo />
      </MapView>
    </View>
  );
}

useState Hook 为您提供两件事:

  • 在渲染中持续存在的值
  • 用于更新该值并触发重新渲染的 API。

如果您有一个不关心重新渲染的用例,但您确实需要在渲染之间保留一个值,那么您需要useState的一半来让您在渲染之间保留一个值,而不是另一半触发一个重新渲染。

这正是useRef所做的

useRef() 钩子不仅仅用于 DOM 引用。 “ref”对象是一个通用容器,它的当前属性是可变的并且可以保存任何值

https://reactjs.org/docs/hooks-faq.html#is-there-something-like-instance-variables

获取标记的引用:

const markerRef = useRef();

假设您想将标记移动到 map 上的长按点:

<MapView
 provider={Platform.OS === 'ios' ? PROVIDER_DEFAULT : PROVIDER_GOOGLE}
 style={styles.map}
 pitchEnabled={false}
 initialRegion={userLocation.current}
 onLongPress={handleUserMarkMap}
 onRegionChange={handleMapDeltaChange}>
 <Marker
   ref={markerRef}
   draggable
   coordinate={markedMapLocation.current}
   onDragEnd={handleUserMarkMap}
  />
 </MapView>

你会按如下方式处理这个案例:

const handleUserMarkMap = event => {
 const selectedCoordinate = event?.nativeEvent?.coordinate;
 ....
 // this is the magic function
 markerRef.current.animateMarkerToCoordinate(selectedCoordinate);
};

因此,这将使您无需重新渲染 map 即可移动标记

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM