Имеется следующий компонент карты, использующий 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>
);
};
Из другого компонента приходит свойство id, на основе которого выбирается задача, на маркере которой происходит центрирование карты. С этим аспектом все в порядке. Однако смена стейта и центрирование должно также происходить и при тапе на маркер задачи, чего в данный момент нет. Полагаю, что дело в первых трех строчках внутри
useEffect()
if (taskId) {
selectTask(taskId);
}
Однако при их удалении перестает работать центрирование. Вынос
selectTask(taskId)
вызывает ошибку
"Too many re-renders"
. Как решить проблему смены стейта и последующего центрирования при тапе на маркер?