如果我在移动 chrome 上 5 秒内切换得太快,useEffect 将无法从 openWeatherAPI 获取数据。 但等5秒,重新切换页面,就可以读取并显示了。
我的天气应用程序由 Next.js 应用程序路由部署在 vercel 上,有两个页面“/”、“/week”。 我使用 getPosition() 获取纬度和经度,使用 fetchApi() 获取天气数据,并使用 切换页面。
主页(“/”)
"use client";
import { fetchApi } from "@/api/fetchApi";
import InfoBox from "@/components/InfoBox";
import RainChart from "@/components/RainChart";
import TempChart from "@/components/TempChart";
import { getPosition } from "@/utils/getPosition";
import { unixToDate } from "@/utils/unixToDate";
import { unixToTime } from "@/utils/unixToTime";
import { useEffect, useState } from "react";
export default function Home() {
const [date, setDate] = useState<string>("");
const [time, setTime] = useState<string>("");
const [desc, setDesc] = useState<string>("");
const [feel, setFeel] = useState<number>(0);
const [hourFeel, setHourFeel] = useState<number[]>([]);
const [hourRain, setHourRain] = useState<number[]>([]);
useEffect(() => {
getPosition()
.then((position) => {
fetchApi(position.coords.latitude, position.coords.longitude, "metric")
.then((data: any) => {
setTime(unixToTime(data.current.dt));
setDate(unixToDate(data.current.dt));
setDesc(data.current.weather[0].description);
setFeel(Math.round(data.current.feels_like));
const hourFeelData: number[] = [];
const hourRainData: number[] = [];
for (let i = 0; i < 24; i++) {
hourFeelData.push(Math.round(data.hourly[i].feels_like));
setHourFeel(hourFeelData);
hourRainData.push(Math.round(data.hourly[i].pop * 100));
setHourRain(hourRainData);
}
})
.catch((err) => {
console.error(err);
});
})
.catch((err) => {
console.log(err);
});
}, []);
return (
<main>
<div className="mt-5 flex justify-evenly">
<InfoBox date={date} time={time} content={desc} />
<InfoBox label="現在體感" content={`${feel}℃`} />
</div>
<TempChart data={hourFeel} />
<RainChart data={hourRain} />
</main>
);
}
weekPage(“/week”)
"use client";
import { fetchApi } from "@/api/fetchApi";
import { getPosition } from "@/utils/getPosition";
import { unixToDate } from "@/utils/unixToDate";
import { useEffect, useState } from "react";
import DaysDetails from "@/components/DaysDetails";
const WeekPage = () => {
const loop = [];
for (let i = 0; i < 8; i++) {
loop.push(i);
}
const [date, setDate] = useState<string[]>(["", "", "", "", "", "", "", ""]);
const [desc, setDesc] = useState<string[]>(["", "", "", "", "", "", "", ""]);
const [dayFeel, setDayFeel] = useState<number[]>([0, 0, 0, 0, 0, 0, 0, 0]);
const [eveFeel, setEveFeel] = useState<number[]>([0, 0, 0, 0, 0, 0, 0, 0]);
const [rain, setRain] = useState<number[]>([0, 0, 0, 0, 0, 0, 0, 0]);
useEffect(() => {
getPosition()
.then((position) => {
fetchApi(position.coords.latitude, position.coords.longitude, "metric")
.then((data: any) => {
const dateData: string[] = [];
const descData: string[] = [];
const rainData: number[] = [];
const eveFeelData: number[] = [];
const dayFeelData: number[] = [];
for (let i = 0; i < 8; i++) {
dateData.push(unixToDate(data.daily[i].dt));
setDate(dateData);
descData.push(data.daily[i].weather[0].description);
setDesc(descData);
dayFeelData.push(Math.round(data.daily[i].feels_like.day));
setDayFeel(dayFeelData);
eveFeelData.push(Math.round(data.daily[i].feels_like.eve));
setEveFeel(eveFeelData);
rainData.push(Math.round(data.daily[i].pop * 100));
setRain(rainData);
}
})
.catch((err) => {
console.error(err);
});
})
.catch((err) => {
console.log(err);
});
}, []);
return (
<div className="flex h-[43.75rem] flex-col items-center justify-evenly">
{loop.map((i) => (
<DaysDetails
key={i}
date={date[i]}
desc={desc[i]}
rain={`${rain[i]}%`}
dayFeel={`${dayFeel[i]}℃`}
eveFeel={`${eveFeel[i]}℃`}
/>
))}
</div>
);
};
export default WeekPage;
布局中的页面切换
"use client";
import Link from "next/link";
import { useState } from "react";
const PageSwitcher: React.FC = () => {
const [page, setPage] = useState("now");
return (
<div className="flex justify-center">
<Link
href="/"
onClick={() => setPage("now")}
className={`flex h-14 w-[11.5rem] items-center justify-center ${page === "now" ? "bg-slate-300" : "bg-inherit"}`}
>
NOW
</Link>
<Link
href="/week"
onClick={() => setPage("7days")}
className={`flex h-14 w-[11.5rem] items-center justify-center ${page === "7days" ? "bg-slate-300" : "bg-inherit"}`}
>
7 DAYS
</Link>
</div>
);
};
export default PageSwitcher;
我认为问题是useEffect依赖项([]),也许到页面并不意味着初始渲染?
我尝试使用 USB 调试将我的手机链接到桌面,以查看真实的移动 chrome devTool 网络页面。
并与桌面devTool-Network页面进行比较。
我只是希望它能像台式机一样在 Android 上正常获取数据。 请给我一些建议,谢谢!
检查代码后,就像您所说的“useEffect依赖项([])”。
在这两个组件中,您都为 useEffect 使用空依赖数组 ([]),这意味着效果只会在初始渲染后运行一次。
因此,如果由于快速页面切换而快速卸载并重新挂载组件,则 useEffect 将不会再次运行,除非其依赖项发生变化。
还可以考虑将位置包含为依赖项,以便在地理位置发生变化时触发 useEffect。