Answer the question
In order to leave comments, you need to log in
How to fix map centering issue (react-native-maps) when tapping on a marker?
I have the following map component using react-native-maps:
const TasksMapScreen: React.FunctionComponent<Props> = () => {
const route = useRoute();
const tasks = [
{
id: 5602481,
category: 'lights',
text: 'задача 1',
location: 'адрес 1',
latlng: {
latitude: 54.1925489,
longitude: 37.6705917,
},
distance: 200,
date: '08.06.2019',
price: 300,
isResolved: false,
reworkings: 0,
},
{
id: 5602482,
category: 'garbage',
text: 'задача 2',
location: 'адрес 2',
latlng: {
latitude: 54.1541381,
longitude: 37.5843054,
},
distance: 200,
date: '08.06.2019',
price: 0,
deadline: '18.06.2019',
isResolved: false,
reworkings: 0,
},
{
id: 5602483,
category: 'garbage',
text: 'задача 3',
location: 'адрес 3',
latlng: {
latitude: 54.1879952,
longitude: 37.5988459,
},
distance: 200,
date: '08.06.2019',
price: 0,
deadline: '18.06.2019',
isOverdue: true,
isResolved: false,
reworkings: 0,
},
{
id: 5602484,
category: 'lights',
text: 'задача 4',
location: 'адрес 4',
latlng: {
latitude: 54.1571578,
longitude: 37.5970531,
},
distance: 200,
date: '08.06.2019',
price: 0,
deadline: '18.06.2019',
rating: 5,
isResolved: true,
reworkings: 2,
},
{
id: 5602489,
category: 'lights',
text: 'адрес 5',
location: 'задача 5',
latlng: {
latitude: 54.1886121,
longitude: 37.5982382,
},
distance: 200,
date: '08.06.2019',
price: 0,
isResolved: false,
reworkings: 0,
},
];
const tasksObj = tasks.reduce((acc, task) => {
acc[task.id] = task;
return acc;
}, {});
const tasksFirstId = Object.keys(tasksObj)[0];
const initialMarkerLatlng = tasksObj[tasksFirstId].latlng;
const taskId = route.params?.taskId;
const [zoom, setZoom] = useState(14);
const [task, selectTask] = useState(null);
const region = {
...initialMarkerLatlng,
latitudeDelta: 0.0922,
longitudeDelta: 0.0421,
};
const mapView = useRef(null);
useEffect(() => {
if (taskId) {
selectTask(taskId);
}
if (mapView.current) {
mapView.current?.animateCamera(
{
center: tasksObj[task].latlng,
zoom: 15,
},
1000,
);
}
}, [taskId, task, tasksObj]);
return (
<View style={styles.container}>
<MapView
ref={mapView}
style={styles.map}
minZoomLevel={zoom}
maxZoomLevel={zoom}
showsCompass={false}
initialRegion={region}>
{Object.values(tasksObj).map((task) => (
<Marker
coordinate={task.latlng}
title=""
key={task.id}
onPress={() => selectTask(task.id)}>
<TaskMarker
category={task.category}
price={task.price}
isResolved={task.isResolved}
reworkings={task.reworkings}
/>
</Marker>
))}
</MapView>
</View>
);
};
useEffect()
if (taskId) {
selectTask(taskId);
}
selectTask(taskId)
causes an error "Too many re-renders"
. How to solve the problem of changing the state and then centering when tapping on a marker?
Answer the question
In order to leave comments, you need to log in
I changed the code in this way - I added the second one to the code useEffect()
to change the state task
based on the incoming id
one, while the first one useEffect()
remains responsible for centering the map based on the existing one task
:
const [zoom, setZoom] = useState(14);
const [task, selectTask] = useState(undefined);
const mapView = useRef(null);
useEffect(() => {
if (task) {
if (mapView.current) {
mapView.current?.animateCamera(
{
center: task.latlng,
zoom: 15,
},
1000,
);
}
}
}, [task]);
useEffect(() => {
if (route.params?.taskId) {
// @ts-ignore
selectTask(tasks.find((t) => t.id === route.params.taskId));
}
}, [route.params]);
return (
<View style={styles.container}>
<MapView
ref={mapView}
style={styles.map}
minZoomLevel={zoom}
maxZoomLevel={zoom}
showsCompass={false}
initialRegion={region}
onPress={() => selectTask(undefined)}>
{tasks.map((task) => (
<Marker
coordinate={task.latlng}
title=""
key={task.id}
// @ts-ignore
onPress={() => selectTask(task)}>
<TaskMarker
category={task.category}
price={task.price}
isResolved={task.isResolved}
reworkings={task.reworkings}
/>
</Marker>
))}
</MapView>
</View>
);
};
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question