Map 返回 2 倍于同一对象时应只返回 1



我正在尝试从 API 获取数据,当我尝试地图数组以获取有趣的数据时,我的程序下载了第一次搜索 2 次相同的对象,第二次和另一次搜索 6 次。
我不知道为什么。我检查了useEffect,这个函数只获取一次预期的内容。
问题是当我想显示 5 天并且我想显示每天的每小时预测时。
期望的:地图在 5 天内返回我 1 个
数组我现在收到什么:map 在相同的 5 天内返回我 2 个相同的数组。

这是代码:

应用.js

import React, { useState} from 'react';
import Form from './Form';
import Weather from './Weather';
import useSyncFetch from '../services/useSyncFetch';
const App = () => {
const url = "http://datapoint.metoffice.gov.uk/public/data/val/wxfcs/all/json";
const key = "*********************";
const [idCity, setIdCity] = useState();
const data = useSyncFetch(url + "/sitelist?" + key);
return (
<div className="wrapper">
<Form
setIdCity={setIdCity}
data={data}
/>
<Weather 
idCity={idCity}
url={url}
apiKey={key}
/>
</div>
);
}
export default App;

形式.js

import React, { useState } from 'react';
const Form = ({setIdCity, data}) => {
const [cityName, setCityName] = useState('');

const findId = (e) =>{
const cities = data.Locations.Location;
cities.forEach(city => {
const userInput = cityName.toLowerCase();
const dataCitiesName = city.name.toLowerCase();
if(userInput === dataCitiesName){
console.log(city.name, city.id)
return setIdCity(city.id)
}
});
}
const handleClick = (e) => {
e.preventDefault();
findId();
}
const handleChange = e => {
setCityName(e.target.value)
}

return (
<form>
<label htmlFor="location">Location: </label>
<input 
onChange={handleChange} 
type="text" 
name="location" 
id="location" />
<button onClick={handleClick}>Check</button>
</form>
);
}
export default Form;

天气.js

import React, { useState, useEffect } from 'react';
import Day from './Day';
const Weather = ({ idCity, url, apiKey }) => {
const [location, setLocation] = useState({});
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
fetch(url + `/${idCity}?res=3hourly&` + apiKey)
.then(response => response.json())
.then(data => {
setLocation(data.SiteRep.DV.Location);
setIsLoading(false)
})
}, [apiKey, idCity, url])
if (isLoading) {
return (
<h2>Please write location and click check</h2>
)
} else if(!isLoading){
const days = location.Period
return (
<div>
<p>{location.name}</p>
<p>{location.country}</p>
{days.map(element => (
<Day 
key={element.value}
days={days}
hourlyForecast={element.Rep}
date={element.value}
/>
))}
{console.log(days, "Days")}
</div>
)
}
}
// //Bug is with rerender should be days.map(element => {
//     element.Rep.map(day => )
// }) 
export default Weather;

import React from 'react';
import Hours from './Hours'
const Day = ({ days, date, hourlyForecast }) => {
const dayDate = date.slice(0, 10);
const forecastForHour = hourlyForecast.map(element => (
<Hours
key={element.$}
hours={hourlyForecast}
/>
))
return (
<div>
<p>{dayDate}</p>
{forecastForHour}
{console.log(hourlyForecast, "Hours")}
</div>
);
}
export default Day;

小时.js

import React, { useState } from 'react';
const weatherTypes = [
{ id: 0, weather: "Clear night" },
{ id: 1, weather: "Sunny day" },
{ id: 2, weather: "Partly cloudy (night)" },
{ id: 3, weather: "Partly cloudy (day)" },
{ id: 4, weather: "Not used" },
{ id: 5, weather: "Mist" },
{ id: 6, weather: "Fog" },
{ id: 7, weather: "Cloudy" },
{ id: 8, weather: "Overcast" },
{ id: 9, weather: "Light rain shower (night)" },
{ id: 10, weather: "Light rain shower (day)" },
{ id: 11, weather: "Drizzle" },
{ id: 12, weather: "Light rain" },
{ id: 13, weather: "Heavy rain shower (night)" },
{ id: 14, weather: "Heavy rain shower (day)" },
{ id: 15, weather: "Heavy rain" },
{ id: 16, weather: "Sleet shower (night)" },
{ id: 17, weather: "Sleet shower (day)" },
{ id: 18, weather: "Sleet" },
{ id: 19, weather: "Hail shower (night)" },
{ id: 20, weather: "Hail shower (day)" },
{ id: 21, weather: "Hail" },
{ id: 22, weather: "Light snow shower (night)" },
{ id: 23, weather: "Light snow shower (day)" },
{ id: 24, weather: "Light snow" },
{ id: 25, weather: "Heavy snow shower (night)" },
{ id: 26, weather: "Heavy snow shower (day)" },
{ id: 27, weather: "Heavy snow" },
{ id: 28, weather: "Thunder shower (night)" },
{ id: 29, weather: "Thunder shower (day)" },
{ id: 30, weather: "Thunder" },
]
const Hours = ({ hours }) => {
let temperature;
let feelLikeTemperature;
let wind;
let weatherType;
let visibility;
let UV;
let time;
let pop;
let weatherText;
const hour = hours.map(element => {
switch (element.V) {
case "VP":
visibility = "Very poor - less than 1 km "
break;
case "PO":
visibility = "Poor - Between 1-4 km "
break;
case "MO":
visibility = "Moderate - Between 4-10 km"
break;
case "GO":
visibility = "Good - Between 10-20 km"
break;
case "VG":
visibility = "Very good - Between 20-40 km"
break;
case "EX":
visibility = "Excellent - More than 40 km"
break;
default:
visibility = "Unknown"
break;
}
if (element.U <= 2) {
UV = "Low exposure. No protection required. You can safely stay outside"
} else if (element.U > 2 && element.U < 5) {
UV = "Moderate exposure. Seek shade during midday hours, cover up and wear sunscreen"
} else if (element.U === 6 || element.U === 7) {
UV = "High exposure. Seek shade during midday hours, cover up and wear sunscreen"
} else if (element.U >= 8 && element.U < 11) {
UV = "Very high. Avoid being outside during midday hours. Shirt, sunscreen and hat are essential"
} else {
UV = "Extreme. Avoid being outside during midday hours. Shirt, sunscreen and hat essential."
}
weatherType = element.W;
temperature = element.T;
time = element.$/60;
feelLikeTemperature = element.F;
wind = element.S;
pop = element.Pp;
})
const checkWeatherType = weatherTypes.map(type=>{
// console.log(weatherType)
if(weatherType === type.id) return weatherText = type.weather;
else return weatherText=type.weather;
})
return (
<div>
<p>Time {time < 10 ? "0" + time + ":00" : time + ":00"}</p>
<p>Temperature: {temperature} Celcius</p>
<p>Feel like temperature: {feelLikeTemperature} Celcius</p>
<p>Wind: {wind} mph</p>
<p>Weather Type: {weatherText}</p>
<p>Visibility: {visibility}</p>
<p>Max UV index: {UV}</p>
<p>Precipitation Probability: {pop} %</p>
</div>
);
}
export default Hours;

尝试将"useSyncFetch"包装在"useEffect"中,否则每次渲染都会调用此函数。

相关内容

  • 没有找到相关文章

最新更新