开发者问题收集

无法将来自 API 的数据映射到 React 中的渲染组件

2022-05-23
419

我需要为 axios.get 返回的每个位置渲染一个 Leaflet 标记(它返回一个对象数组,每个对象都是一个位置),但尝试这样做时出现两个错误:

-“未捕获的 TypeError:data.map 不是函数”; -“警告:无法对尚未安装的组件执行 React 状态更新。这表明您的渲染函数中存在副作用,该函数稍后会异步调用尝试更新组件。请将此工作移至 useEffect”。

我已经使用本地示例对其进行了测试,并且它可以正常工作。问题是让它使用从承诺中检索到的数据。

import { useState } from "react"
import { MapContainer, TileLayer, Marker, Popup } from 'react-leaflet'
import { Link } from "react-router-dom"
import axios from "axios"

import "../styles/Map.css"

export default function Map() {
    const [data, setData] = useState({})

    async function getData() {
        await axios.get("http://localhost:8080")
            .then(data => data.json())
            .then(data => setData(data))
            .catch(data => data = "")
    }

    getData()
    
    return (
        <main>
            <MapContainer center={[-23.6334841179179, -46.46843854558035]} zoom={13} scrollWheelZoom={true}>
                <TileLayer
                    attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
                    url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
                />
                <Marker position={[-23.6334841179179, -46.46843854558035]}>
                    <Popup>{"My house <3"}</Popup>
                </Marker>
                {
                    data && data.map(loc => (
                        <Marker key={data.id} position={[loc.latitude, loc.longitude]}>
                            <Popup>{loc.name}</Popup>
                        </Marker>
                    ))
                }
            </MapContainer>

            <button><Link to="/register">Register new Location</Link></button>
        </main>
    )
}
3个回答

请尝试像这样使用 data?.map

import { MapContainer, TileLayer, Marker, Popup } from 'react-leaflet'
import { Link } from "react-router-dom"
import axios from "axios"

import "../styles/Map.css"

export default function Map() {
    const [data, setData] = useState([])

    async function getData() {
        await axios.get("http://localhost:8080")
            .then(data => data.json())
            .then(data => setData(data))
            .catch(data => data = "")
    }

    useEffect(()=>{
       getData();
    },[])
    
    return (
        <main>
            <MapContainer center={[-23.6334841179179, -46.46843854558035]} zoom={13} scrollWheelZoom={true}>
                <TileLayer
                    attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
                    url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
                />
                <Marker position={[-23.6334841179179, -46.46843854558035]}>
                    <Popup>{"My house <3"}</Popup>
                </Marker>
                {
                    data?.map(loc => (
                        <Marker key={data.id} position={[loc.latitude, loc.longitude]}>
                            <Popup>{loc.name}</Popup>
                        </Marker>
                    ))
                }
            </MapContainer>

            <button><Link to="/register">Register new Location</Link></button>
        </main>
    )
}```
BTSM
2022-05-23

使初始默认值一个数组而不是对象。

813010652

对象没有映射方法,但是空数组应该。

Luke Schlangen
2022-05-23

尝试一下。

    async function getData() {
        let data = await axios.get("http://localhost:8080")
        data = data?.json();
        if(data !== null) setData(data);
    }
    useEffect(() => { getData() }, []);
StormyTalent
2022-05-23