Реагируйте на рендеринг выноски собственных карт - PullRequest
2 голосов
/ 22 января 2020

Я использую react-native-maps для отображения маркеров для вокзалов в моем районе. Каждый маркер имеет выноску с данными о приближающихся поездах в реальном времени.

Проблема в том, каждый выносится в фоновом режиме для каждого маркера, который у меня есть на карте. Также каждый вызов перерисовывается, так как у меня есть новые данные из API реального времени. Это вызывает отображение сотен представлений, даже если мне нужен только вызов маркера, который был нажат. скриншот приложения

Есть ли способ убедиться, что никакие выноски не отображаются, пока пользователь нажимает на определенный c маркер? После прессы; Я также хочу убедиться, что указанная c отметка маркера отображается и отображается.

Мой код:

MapScreen:

const MapScreen = props => {
  // get user location from Redux store
  // this is used to center the map
  const { latitude, longitude } = useSelector(state => state.location.coords)

  // The MapView and Markers are static
  // We only need to update Marker callouts after fetching data
  return(
    <SafeAreaView style={{flex: 1}}>
    <MapView
        style={{flex: 1}}
        initialRegion={{
          latitude:  parseFloat(latitude) || 37.792874,
          longitude: parseFloat(longitude) || -122.39703,
          latitudeDelta: 0.06,
          longitudeDelta: 0.06
        }}
        provider={"google"}
      >
        <Markers />
      </MapView>
      </SafeAreaView>
  )
}

export default MapScreen

Компонент маркеров:

const Markers = props => {
  const stationData = useSelector(state => state.stationData)

  return stationData.map((station, index) => {
    return (
      <MapView.Marker
        key={index}
        coordinate={{
          // receives station latitude and longitude from stationDetails.js
          latitude: parseFloat(stationDetails[station.abbr].gtfs_latitude),
          longitude: parseFloat(stationDetails[station.abbr].gtfs_longitude)
        }}
        image={stationLogo}
        zIndex={100}
        tracksInfoWindowChanges={true}
      >
        <MapView.Callout
          key={index}
          tooltip={true}
          style={{ backgroundColor: "#ffffff" }}
        >
          <View style={styles.calloutHeader}>
            <Text style={{ fontWeight: "bold" }}>{station.name}</Text>
          </View>
          <View style={styles.calloutContent}>
            <StationCallout key={index} station={stationData[index]} />
          </View>
        </MapView.Callout>
      </MapView.Marker>
    );
  });
};

Компонент StationCallout:

const StationCallout = (props) => {
  return(
    props.station.etd.map((route, index) => {
      const approachingTrains = function() {
        trainText = `${route.destination} in`;

        route.estimate.map((train, index) => {
          if (index === 0) {
            if (train.minutes === "Leaving") {
              trainText += ` 0`;
            } else {
              trainText += ` ${train.minutes}`;
            }
          } else {
            if (train.minutes === "Leaving") {
              trainText += `, 0`;
            } else {
              trainText += `, ${train.minutes}`;
            }
          }
        });

        trainText += " mins";

        return <Text>{trainText}</Text>;
      };

      return <View key={index}>
      {approachingTrains()}
      </View>;
    })
  )
};

export default StationCallout

1 Ответ

0 голосов
/ 22 января 2020

В ComponentDidMount вы должны получить данные для всех поездов, чтобы все маркеры могли быть установлены на своих позициях. Вы можете сделать это, используя один раз ('value') событие firebase. Это событие извлекает данные только из ссылки, когда она вызывается, поэтому вы будете вызывать ее, когда компонент монтировал.

ПРОЧИТАЙТЕ БОЛЬШЕ О РАЗ ('VALUE')

Теперь, когда у вас есть все указатели на своих позициях, пользователь может щелкнуть любой из указателей, чтобы отслеживать его движение вправо?

Таким образом, каждый указатель должен иметь что-то уникальное, например Train ID или что-то еще, я не знаю структуру вашей базы данных, поэтому я предполагаю, что у вас есть ID поезда. Теперь в функции маркера onPress вы должны передать этот TrainID.

пример:

onPress={()=> this.TrackSpecificTrain(trainID)  }

Теперь в функции TrackSpecificTrain вы должны вызывать защиту базы данных с идентификатором поезда и пожарной базой on ('value') Событие, теперь вы будете продолжать получать данные в реальном времени о выбранном поезде, и вы можете обновить ваше местное состояние stationData с новыми данными, поступающими с firebase.

Пример


TrackSpecificTrain=(trainID)=>{
const ref = database().ref(`YourTrainsRef/${trainID}/`)
  ref.on('value',( snapshot)=>{
           //Update your local state with new data in snapshot
        })
}


RemoveTracker=(trainID)=>{
const ref = database().ref(`YourTrainsRef/${trainID}/`)

ref.off("value")

}

Теперь здесь мы также используем RemoveTracker, потому что вам может потребоваться прекратить отслеживание предыдущего поезда, если пользователь нажимает на другой маркер, чтобы он начал отслеживать идентификатор поезда на новом маркер и прекратить отслеживание предыдущего!.

...