Javascript “错误”;无法读取属性';地图';“未定义”的定义;json获取之后

Javascript “错误”;无法读取属性';地图';“未定义”的定义;json获取之后,javascript,json,reactjs,Javascript,Json,Reactjs,从服务器获取json文件后,请继续获取以下错误 TypeError:无法读取未定义的属性“map” 我知道我正在获取的locationsData存在问题,但我假设由于解析数据的格式,它已经具有数组格式(请参见下面的示例) 在分配(locationsData=json;)之前,locationsData是未定义的,如您在初始声明中所述:let locationsData 因此undefined.map()将抛出错误,您可以这样做以保持一致的行为: let locationsData = [];

从服务器获取json文件后,请继续获取以下错误

TypeError:无法读取未定义的属性“map”

我知道我正在获取的locationsData存在问题,但我假设由于解析数据的格式,它已经具有数组格式(请参见下面的示例)

在分配(
locationsData=json;
)之前,
locationsData
未定义的
,如您在初始声明中所述:
let locationsData

因此
undefined.map()
将抛出错误,您可以这样做以保持一致的行为:

let locationsData = [];
或者,您可以在调用
.map()
函数之前进行验证:

  {Array.isArray(locationsData) && locationsData.map((loc) => (
      <Marker
        key={loc._id}
        position={{
          lat: loc.gps[0],
          lng: loc.gps[1],
        }}
        onClick={() => {
          setSelectedLoc(loc);
        }}
      />
  ))}
{Array.isArray(locationsData)和&locationsData.map((loc)=>(
{
设置选定的loc(loc);
}}
/>
))}

正如@Gabriele所指出的,fetch操作被放置在组件的外部。可以执行此操作以确保正确指定结果,并且组件将渲染结果:

function Map() {
  const [selectedLoc, setSelectedLoc] = useState(null);
  const [locationsData, setLocationsData] = useState([]);

  useEffect(() => {
    fetch("http:///locations")
      .then(u => u.json())
      .then(json => setLocationsData(json));
  }, []); // Empty dependency, acts similar to componentDidMount

  return (
    <div className="App">
      <GoogleMap
        defaultZoom={14}
        defaultCenter={{ lat: 49.55848, lng: 23.312481 }}
      >
        {locationsData.map((loc) => (
          <Marker
            key={loc._id}
            position={{
              lat: loc.gps[0],
              lng: loc.gps[1],
            }}
            onClick={() => {
              setSelectedLoc(loc);
            }}
          />
        ))}

        {selectedLoc && (
          <InfoWindow
            position={{
              lat: selectedLoc.gps[0],
              lng: selectedLoc.gps[1],
            }}
            onCloseClick={() => {
              setSelectedLoc(null);
            }}
          >
            <div>
              <h2>{selectedLoc.name}</h2>
            </div>
          </InfoWindow>
        )}
      </GoogleMap>
    </div>
  );
}
函数映射(){
const[selectedLoc,setSelectedLoc]=useState(null);
const[locationsData,setLocationsData]=useState([]);
useffect(()=>{
取回(“http:///locations")
.then(u=>u.json())
。然后(json=>setLocationsData(json));
},[]);//空依赖项,其行为类似于componentDidMount
返回(
{locationsData.map((loc)=>(
{
设置选定的loc(loc);
}}
/>
))}
{selectedLoc&&(
{
setSelectedLoc(空);
}}
>
{selectedLoc.name}
)}
);
}
在分配(
locationsData=json;
)之前,
locationsData
未定义的
,如您在初始声明中所述:
let locationsData

因此
undefined.map()
将抛出错误,您可以这样做以保持一致的行为:

let locationsData = [];
或者,您可以在调用
.map()
函数之前进行验证:

  {Array.isArray(locationsData) && locationsData.map((loc) => (
      <Marker
        key={loc._id}
        position={{
          lat: loc.gps[0],
          lng: loc.gps[1],
        }}
        onClick={() => {
          setSelectedLoc(loc);
        }}
      />
  ))}
{Array.isArray(locationsData)和&locationsData.map((loc)=>(
{
设置选定的loc(loc);
}}
/>
))}

正如@Gabriele所指出的,fetch操作被放置在组件的外部。可以执行此操作以确保正确指定结果,并且组件将渲染结果:

function Map() {
  const [selectedLoc, setSelectedLoc] = useState(null);
  const [locationsData, setLocationsData] = useState([]);

  useEffect(() => {
    fetch("http:///locations")
      .then(u => u.json())
      .then(json => setLocationsData(json));
  }, []); // Empty dependency, acts similar to componentDidMount

  return (
    <div className="App">
      <GoogleMap
        defaultZoom={14}
        defaultCenter={{ lat: 49.55848, lng: 23.312481 }}
      >
        {locationsData.map((loc) => (
          <Marker
            key={loc._id}
            position={{
              lat: loc.gps[0],
              lng: loc.gps[1],
            }}
            onClick={() => {
              setSelectedLoc(loc);
            }}
          />
        ))}

        {selectedLoc && (
          <InfoWindow
            position={{
              lat: selectedLoc.gps[0],
              lng: selectedLoc.gps[1],
            }}
            onCloseClick={() => {
              setSelectedLoc(null);
            }}
          >
            <div>
              <h2>{selectedLoc.name}</h2>
            </div>
          </InfoWindow>
        )}
      </GoogleMap>
    </div>
  );
}
函数映射(){
const[selectedLoc,setSelectedLoc]=useState(null);
const[locationsData,setLocationsData]=useState([]);
useffect(()=>{
取回(“http:///locations")
.then(u=>u.json())
。然后(json=>setLocationsData(json));
},[]);//空依赖项,其行为类似于componentDidMount
返回(
{locationsData.map((loc)=>(
{
设置选定的loc(loc);
}}
/>
))}
{selectedLoc&&(
{
setSelectedLoc(空);
}}
>
{selectedLoc.name}
)}
);
}

使用空数组初始化locationData

let locationsData= [];

使用空数组初始化locationData

let locationsData= [];

您将需要使用
useffect
并在那里进行抓取。您还必须将数据存储在状态中,以便在获取数据后组件将重新呈现

函数映射(){
const[selectedLoc,setSelectedLoc]=useState(null);
const[locationsData,setLocationsData]=useState([]);
useffect(()=>{
取回(“http:///locations")
.然后(函数(u){
返回u.json();
})
.then(函数(json){
setLocationsData(json);
});
}, [])
返回(
{locationsData.map((loc)=>(
{
设置选定的loc(loc);
}}
/>
))}
{selectedLoc&&(
{
setSelectedLoc(空);
}}
>
{selectedLoc.name}
)}
);
}

您将需要使用
useffect
并在那里进行抓取。您还必须将数据存储在状态中,以便在获取数据后组件将重新呈现

函数映射(){
const[selectedLoc,setSelectedLoc]=useState(null);
const[locationsData,setLocationsData]=useState([]);
useffect(()=>{
取回(“http:///locations")
.然后(函数(u){
返回u.json();
})
.then(函数(json){
setLocationsData(json);
});
}, [])
返回(
{locationsData.map((loc)=>(
{
设置选定的loc(loc);
}}
/>
))}
{selectedLoc&&(
{
setSelectedLoc(空);
}}
>
{selectedLoc.name}
)}
);
}

这实际上是在json获取之前,这是您的问题。尝试像,
locationsData&&locationsData.map((loc)=>(…)
这实际上是在json获取之前,这是您的问题。尝试像,
locationsData&&locationsData.map((loc)=>(…)
提取发生在组件外部,结果存储在一个普通变量中。因此组件不会重新呈现。@GabrielePetrioli你说得对,它不在组件内部。让我更新一下答案。谢谢!谢谢,@JeeMok!尝试了所有版本和所有编译的版本。但是我仍然看不到上面的要点映射。我读取值可能有什么问题吗?因为即使只是验证,我也看不到任何点,据我所知,验证至少应该返回映射的静态版本。@MemberUnit验证只是为了避免在没有验证时崩溃