Next.js+TypeScript中RTK Query Hook在useEffect调用报错求助
问题:在useEffect中调用RTK Query的useGetForecastQuery触发无效Hook调用错误
在Next.js + RTK Query + TypeScript项目中,GoogleMapComponent.tsx的useEffect钩子内调用useGetForecastQuery时,出现错误:
Invalid hook call. Hooks can only be called inside of the body of a function component
错误原因
React Hook的核心规则之一是:所有Hook必须直接在函数组件的顶层作用域调用,不能在嵌套函数、循环、条件判断或其他Hook(如useEffect)的回调函数内部调用。
RTK Query生成的useGetForecastQuery本质是React Hook,你在useEffect的回调里调用它,完全违反了这条规则,所以触发了错误。
解决方案
RTK Query的查询Hook本身支持动态参数和自动重新触发查询,不需要手动在useEffect里调用。直接在组件顶层调用Hook,把point作为查询参数的依赖即可:
修改后的GoogleMapComponent.tsx
import React, {ReactElement, useState, useEffect} from 'react'; import GoogleMapReact from 'google-map-react'; import {useGetForecastQuery} from "../redux/slices/weather.slice"; export default function GoogleMap({coords}: { coords: { lat: number; lng: number } }) { const [point, setPoint] = useState([45, 55]); // 直接在组件顶层调用Hook,point变化时自动重新发起查询 const { data, error, isLoading } = useGetForecastQuery({ location: `${point[0]},${point[1]}`, alerts: 'no', aqi: 'no', days: 2 }); // 如需监听查询结果变化,在useEffect中处理数据而非触发查询 useEffect(() => { if (data) { console.log('天气查询结果:', data); } if (error) { console.error('查询失败:', error); } }, [data, error]) const style = { width: '450px', height: '450px' }; const AnyReactComponent = ({text, lat, lng} : {text:string, lat:number, lng:number}): ReactElement => { return ( <> {`${text} ${lat} ${lng}`} </> ) } const onMapClick = ({ x, y, lat, lng, event }: { x: number, y: number, lat: number, lng: number, event: any }) => { setPoint([lat, lng]); } return ( <> <div style={style}> <GoogleMapReact options={{ panControl: false, mapTypeControl: true, scrollwheel: true, }} onClick={onMapClick} bootstrapURLKeys={{ key: process.env.NEXT_PUBLIC_REACT_APP_GOOGLE_MAPS_API_KEY!, language: 'ua', region: 'ua', }} layerTypes={['TrafficLayer', 'TransitLayer']} defaultCenter={coords} center={coords} defaultZoom={1} margin={[0, 0, 0, 0]} > <AnyReactComponent text='Marker' lat={point[0]} lng={point[1]}/> </GoogleMapReact> </div> <div> Google Map </div> {/* 可选:展示查询状态 */} {isLoading && <div>加载天气数据中...</div>} {error && <div>天气数据加载失败</div>} {data && <div>当前温度:{data.current.temp_c}°C</div>} </> ) }
额外修复:WeatherSlice补全查询参数
你的ForecastQueryOptions定义了days参数,但原代码的查询URL未包含该参数,导致API返回默认天数数据,需补上:
// WeatherSlice.ts中修改query部分 query: (forecastQueryOptions: ForecastQueryOptions) => `forecast.json?key=${api_key}&q=${forecastQueryOptions.location}&days=${forecastQueryOptions.days}&aqi=${forecastQueryOptions.aqi}&alerts=${forecastQueryOptions.alerts}`
内容的提问来源于stack exchange,提问作者Vitalii Ponomarov
相关产品推荐
相关产品推荐

