Just learning some nexts.js with rtkquery with typescript and occur this error in useEffect in
GoogleMapComponent.tsx, code below. React site said that i broke some rules of hooks using, but this is functional component, using inside another hook, not a plain js function. dont know what to do. thanks guys.
import React, {ReactElement, useEffect, useState} 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]);
useEffect(() => {
console.log(useGetForecastQuery({location: `${point[0]},${point[1]}`, alerts: 'no', aqi: 'no', days: 2}))
}, [point])
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>
</>
)
}
WeatherSlice.ts
// Need to use the React-specific entry point to allow generating React hooks
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'
import type RootForecast from '../../types/forecast.type'
import type {ForecastQueryOptions} from '../../types/query-options.type'
// Define a service using a base URL and expected endpoints
const api_key = process.env.NEXT_PUBLIC_WEATHER_API_KEY;
export const weatherApi = createApi({
reducerPath: 'weatherApi',
baseQuery: fetchBaseQuery({ baseUrl: 'https://api.weatherapi.com/v1/' }),
endpoints: (builder) => ({
getForecast: builder.query<RootForecast, ForecastQueryOptions>({
query: (forecastQueryOptions: ForecastQueryOptions) => `forecast.json
?
key=${api_key}&
q=${forecastQueryOptions.location}&
aqi=${forecastQueryOptions.aqi}&
alerts=${forecastQueryOptions.alerts}`,
}),
}),
})
// Export hooks for usage in function components, which are
// auto-generated based on the defined endpoints
export const { useGetForecastQuery } = weatherApi
forecast.type.ts autogenerated from json
export interface Location {
name: string;
region: string;
country: string;
lat: number;
lon: number;
tz_id: string;
localtime_epoch: number;
localtime: string;
}
export interface Condition {
text: string;
icon: string;
code: number;
}
export interface Current {
last_updated_epoch: number;
last_updated: string;
temp_c: number;
temp_f: number;
is_day: number;
condition: Condition;
wind_mph: number;
wind_kph: number;
wind_degree: number;
wind_dir: string;
pressure_mb: number;
pressure_in: number;
precip_mm: number;
precip_in: number;
humidity: number;
cloud: number;
feelslike_c: number;
feelslike_f: number;
vis_km: number;
vis_miles: number;
uv: number;
gust_mph: number;
gust_kph: number;
}
export interface Condition2 {
text: string;
icon: string;
code: number;
}
export interface Day {
maxtemp_c: number;
maxtemp_f: number;
mintemp_c: number;
mintemp_f: number;
avgtemp_c: number;
avgtemp_f: number;
maxwind_mph: number;
maxwind_kph: number;
totalprecip_mm: number;
totalprecip_in: number;
avgvis_km: number;
avgvis_miles: number;
avghumidity: number;
daily_will_it_rain: number;
daily_chance_of_rain: number;
daily_will_it_snow: number;
daily_chance_of_snow: number;
condition: Condition2;
uv: number;
}
export interface Astro {
sunrise: string;
sunset: string;
moonrise: string;
moonset: string;
moon_phase: string;
moon_illumination: string;
}
export interface Condition3 {
text: string;
icon: string;
code: number;
}
export interface Hour {
time_epoch: number;
time: string;
temp_c: number;
temp_f: number;
is_day: number;
condition: Condition3;
wind_mph: number;
wind_kph: number;
wind_degree: number;
wind_dir: string;
pressure_mb: number;
pressure_in: number;
precip_mm: number;
precip_in: number;
humidity: number;
cloud: number;
feelslike_c: number;
feelslike_f: number;
windchill_c: number;
windchill_f: number;
heatindex_c: number;
heatindex_f: number;
dewpoint_c: number;
dewpoint_f: number;
will_it_rain: number;
chance_of_rain: number;
will_it_snow: number;
chance_of_snow: number;
vis_km: number;
vis_miles: number;
gust_mph: number;
gust_kph: number;
uv: number;
}
export interface Forecastday {
date: string;
date_epoch: number;
day: Day;
astro: Astro;
hour: Hour[];
}
export interface Forecast {
forecastday: Forecastday[];
}
export default interface RootForecast {
location: Location;
current: Current;
forecast: Forecast;
}
and query-options.type.ts
export interface ForecastQueryOptions {
location: string,
days: number,
aqi: string,
alerts: string
}
CodePudding user response:
You're using the useGetForecastQuery
-hook inside another function (callback to useEffect
in your case). That's not allowed with hook functions, hooks can only be called at top-level inside a component or hook function.
See: https://reactjs.org/docs/hooks-rules.html#only-call-hooks-at-the-top-level