41 lines
1.1 KiB
TypeScript
41 lines
1.1 KiB
TypeScript
|
|
import { useEffect, useState } from 'react'
|
|||
|
|
import { fetchWeather, type WeatherResult } from '../api/weather'
|
|||
|
|
|
|||
|
|
export interface WeatherState {
|
|||
|
|
loading: boolean
|
|||
|
|
/** 后端返回的结果(含限流/未配置等业务态);网络错误时为 null */
|
|||
|
|
data: WeatherResult | null
|
|||
|
|
/** 网络层错误(后端不可达) */
|
|||
|
|
error: boolean
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 拉取天气。默认每 30 分钟刷新一次(后端有 10 分钟缓存与每日限流,
|
|||
|
|
* 所以前端即便频繁挂载也不会浪费上游额度)。
|
|||
|
|
*/
|
|||
|
|
export function useWeather(intervalMs = 30 * 60 * 1000): WeatherState {
|
|||
|
|
const [state, setState] = useState<WeatherState>({ loading: true, data: null, error: false })
|
|||
|
|
|
|||
|
|
useEffect(() => {
|
|||
|
|
let cancelled = false
|
|||
|
|
|
|||
|
|
const load = async () => {
|
|||
|
|
try {
|
|||
|
|
const data = await fetchWeather()
|
|||
|
|
if (!cancelled) setState({ loading: false, data, error: false })
|
|||
|
|
} catch {
|
|||
|
|
if (!cancelled) setState({ loading: false, data: null, error: true })
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
load()
|
|||
|
|
const id = setInterval(load, intervalMs)
|
|||
|
|
return () => {
|
|||
|
|
cancelled = true
|
|||
|
|
clearInterval(id)
|
|||
|
|
}
|
|||
|
|
}, [intervalMs])
|
|||
|
|
|
|||
|
|
return state
|
|||
|
|
}
|