Я пытаюсь визуализировать маркеры листовок с помощью React Leaflet с данными, полученными из API с использованием useEffect. Маркеры не отображаются, несмотря на то, что данные о местоположении на момент объявления маркера были ненулевыми (предположительно, из-за использования условного рендеринга, хотя я уже не так уверен).
Код для useEffect:
const [arr, setArr] = React.useState([]);
const [dataLoaded, setDataLoaded] = React.useState(false);
useEffect(() => {
axios.get('http://localhost:8000/get-data/')
.then(res => {
if (res.data) {
const data = res.data
for (let i = 0; i < data.length; i++) {
arr.push(data[i])
}
}
})
.then(res => {
if ( arr.length > 0) {
setDataLoaded(true)
}
})
}, [])
Код для рендеринга маркеров:
{ dataLoaded ? console.info(arr[0].latitude, arr[0].longitude) : null}
{ dataLoaded ? <Marker position = {[parseFloat(arr[0].latitude), parseFloat(arr[0].longitude)]}>
<Popup>
A pretty CSS3 popup. <br /> Easily customizable.
</Popup>
</Marker> : <></> }
Это пример того, как я пытаюсь визуализировать первый набор координат из моего массива данных. Я включил журналы консоли для отладки, которые выводят значения 36,77 и -199,41 для широты и долготы соответственно. Это те же переменные, которые используются для определения положения маркера. Однако по какой-то причине маркер не отображается на моей карте. Если я введу значения [36,77, -119,41] непосредственно в его позицию, маркер появится. Есть идеи, почему это происходит?
Редактировать: здесь скриншот моего массива данных после заполнения.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Во-первых, обновление state типа arr должно находиться внутри setArr, также вам необходимо изменить ссылку array, использование push для обновления arr не приведет к повторной визуализации компонента.
Сначала useEffect с пустой зависимостью вы устанавливаете значение arr.
useEffect(() => {
axios.get('http://localhost:8000/get-data/')
.then(res => {
if (res.data) {
setArr(prevArr => [...prevArr, ...res.data]);
}
})
}, []);
Затем другой useEffect с зависимостью arr, чтобы установить dataLoaded
useEffect(() => {
if (arr.length > 0) {
setDataLoaded(true);
}
}, [arr]);
Я бы изменил ваш код на что-то вроде этого
const [arr, setArr] = React.useState([]);
const [dataLoaded, setDataLoaded] = React.useState(false);
useEffect(() => {
axios.get('http://localhost:8000/get-data/')
.then(res => {
if (res.data) {
const data = res.data
const items = []
data.forEach(item => items.push(item))
setArr(items)
}
})
.then(res => {
//here remove the condition arr.length > 0
//instead you should have conditional rendering in your app
//so if the data is loaded display <>No Items Found</> or something
setDataLoaded(true)
})
}, [])
причина, по которой вы хотите удалить условный setDataLoaded(true), заключается в том, что если вы извлекаете и выборка возвращает [], то ваш dataLoaded имеет значение false, даже если на самом деле загрузка завершена. Вы также уверены, что получаете данные? например, если вы добавите console.info(data) в свою выборку, вы увидите, что она загружается?
Существует также хакерский способ принудительного повторного рендеринга, выполнив что-то вроде этого
const [isRerender, setIsRerender] = React.useState(false)
тогда вы хотели бы добавить что-то подобное в конце вашего вызова API
.finally(() => {setIsRerender(!isRerender)})
Я НЕ рекомендую это, но я использовал это раньше, и это возможно. Но на самом деле это должно быть крайней мерой, потому что ваш код должен работать.
Если какой-либо мой код сбивает с толку или не имеет смысла, дайте мне знать, и я объясню более подробно.
Привет, спасибо за комментарий! Я решил проблему, и она не была связана с useEffect, однако я согласен, что этому методу следует отдать предпочтение.