Как запустить крючок реакции-листовки только при нажатии кнопки

Я пытаюсь реализовать некоторые простые элементы управления движением на карте реагирования-листовки, чтобы после нажатия кнопки можно было «летать» к набору предопределенных координат.

Я знаю, что экземпляр Map, созданный с помощью реакции-листовки, может быть доступен дочерним компонентам, поэтому я использую крючок useMap() в дочернем компоненте, чтобы добиться этого следующим образом в NavigateToMarker.jsx:

import { useMap } from "react-leaflet";

export default function NavigateToMarker({position}) {
    const map = useMap();
    map.flyTo(position, 13)
    return null
}

MainMap.jsx выглядит так:

import NavigateToMarker from './NavigateToMarker';

export default function MainMap() {
  const [position, setPosition] = React.useState([51.607642, -0.129303])

  const handleClick = (position) => {
    setPosition(position)
  }

  <MapContainer>
    <TileLayer />
    <GeoJSON data = {geoJsonData} />
    <NavigateToMarker position = {position} />
  </MapContainer>
  <Button onClick = {() => handleClick([52.309611, -0.139303])}>Fly To Position</Button>
}

Кнопка перемещается в указанную позицию, но моя проблема в том, что код NavigateToMarker запускается каждый раз при рендеринге компонента MainMap.

Я пробовал включить кнопку внутри NavigateToMarker, но поскольку этот компонент затем помещается в компонент MapContainer, кнопки не отображаются, и я не уверен, насколько легко мне удастся применить сетку и стиль CSS с помощью этого метода. .

Есть ли способ гарантировать, что NavigateToMarker вызывается только при нажатии кнопки MainMap.jsx?

Может быть, вам стоит попробовать памятку для NavigateToMarker

EzioMercer 25.07.2024 23:56

Большое спасибо! Кажется, это сработало.

AmazingBergkamp 26.07.2024 09:14
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
2
55
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Как предложил @EzioMercer, обертывание NavigateToMarker в функцию memo привело к желаемому поведению.

//NavigateToMarker.jsx

import { useMap } from "react-leaflet";
import { memo } from 'react';

export default memo(function NavigateToMarker({position, clicked}) {
    const map = useMap();
    if (clicked) map.setView(position, 13)
    return null
})

Чтобы предотвратить запуск NavigateToMarker при первоначальном рендеринге, я добавил логическое свойство, которому присваивается значение true только после вызова обработчика onClick() на кнопке.

//MainMap.jsx

import NavigateToMarker from './NavigateToMarker';

export default function MainMap() {
  const [position, setPosition] = React.useState([51.607642, -0.129303])
  const [clicked, setClicked] = React.useState(false)

  const handleClick = (position) => {
    setClicked(true)
    setPosition(position)
  }

  <MapContainer>
    <TileLayer />
    <GeoJSON data = {geoJsonData} />
    <NavigateToMarker position = {position} clicked = {clicked} />
  </MapContainer>
  <Button onClick = {() => handleClick([52.309611, -0.139303])}>Fly To Position</Button>
}

    

Другие вопросы по теме