reactjstypescriptreact-reduxredux-toolkitrtk-query

Query Polling not getting data when interval time is met


I have been working with Redux-Toolkit Query and trying to get polling to work with an API call that I have. I've pretty much copied the one from the documentation they have and put it in my project. The Pokemon test one in my project works just fine. How ever when I add my API, or one like the dog API listed below. I receive and display the JSON information but when the interval time is met (3, 10 seconds) nothing is updated or fetched, the component background isn't changed and the information isn't updated.

I added the manual refresh button and that works just fine.

I look at the network tab and all I see is the one request and nothing after.

Here is the link the docs working example: RTK polling Pokemon Demo

If I am missing any code please let me know, Ill be sure to post it.

apiSlice.ts

import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'

export const dogsApi = createApi({ 
  reducerPath: 'dogsApi', 
  baseQuery: fetchBaseQuery({ baseUrl: 'https://dog.ceo/api/breeds/image/' }), 
  endpoints: (builder) => ({ 
    getDogs: builder.query({
      query: () => 'random', 
    })         
  })
})

export const { useGetDogsQuery } = dogsApi

store.ts

export const store = configureStore({ 
  reducer: {          
    [dogApi.reducerPath]: dogApi.reducer, 
  }, 
  middleware: getDefaultMiddleware =>
    getDefaultMiddleware()
      .concat(dogApi.middleware)
})

layout.tsx

<Provider store={store}>
  {children}
</Provider>

TestComponent.tsx

const [pollingInterval, setPollingInterval] = React.useState(3000)

const {
  data: doggie,
  error,
  isLoading,
  isFetching,
  refetch
} = useGetDogsQuery( {pollingInterval})

return (
  <div
    style={{
      float: 'left',
      textAlign: 'center',
      ...(isFetching ? { background: '#e6ffe8' } : {}),
    }}
  >
    {error
      ? (<>Oh no, there was an error loading Notices</>) : isLoading
      ? (<>Loading...</>)
      : doggie
        ? (
        <>        
          <h3>Notice Name</h3>
          <div>
            <p>There is and image here</p>
            <div style={{ minWidth: 96, minHeight: 96 }}>
              <img
                src={doggie.message}
                alt={'doggie'}
                style={{ ...(isFetching ? { opacity: 0.3 } : {}) }}
              /> 
            </div>
          </div>
          <div>
            <p>label here</p>
            <p>Select here for intervals</p>
          </div>
          <div>
            <p>There is a button here</p> 
            <label style={{ display: 'block' }}>
              Polling interval {pollingInterval}
            </label>
            
            <button onClick={refetch} disabled={isFetching}>
              {isFetching ? 'Loading' : 'Manually refetch'}
            </button>
            <div>{JSON.stringify(doggie)}</div>
          </div>
        </>  
      ) : ('No Data')
    }
  </div>          
)

Solution

  • Setting/specifying a query polling interval is part of the query options object, the second argument passed to the query hook, after the args argument.

    Signature

    type UseQuery = (
      arg: any | SkipToken,
      options?: UseQueryOptions, // <--
    ) => UseQueryResult
    
    type UseQueryOptions = {
      pollingInterval?: number // <--
      skipPollingIfUnfocused?: boolean
      refetchOnReconnect?: boolean
      refetchOnFocus?: boolean
      skip?: boolean
      refetchOnMountOrArgChange?: boolean | number
      selectFromResult?: (result: UseQueryStateDefaultResult) => any
    }
    

    Update your query hook call to pass pollingInterval in the query options. Since the getDogs endpoint doesn't consume any arguments pass undefined as the query args value.

    const {
      data: doggie,
      error,
      isLoading,
      isFetching,
      refetch,
    } = useGetDogsQuery(undefined, { pollingInterval });