You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 10:15:33