Search code examples
reactjsreduxreact-reduxredux-toolkitrtk-query

RTK query - I am clearly calling one query but for some reason a different one is being actioned


As the title says. This is extremely bizarre to me.

I am quite clearly calling the getThisCategory(genre) query from categoriesApi.js, which should be:

'https://kitsu.io/api/edge/anime?filter%5Bcategories%5D=${genre}'

but in my console there is an error that says:

"GET https://kitsu.io/api/edge/Vampire/anime?limit=20 404".

This looks to me like the query from the animeApi.js file, with the genre parameter passed in. I have no idea why it is calling this query instead.

Please can someone help, this is really frustrating.

Files below:

animeApi.js (the query that SHOULDN'T be getting called but is):

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

const animeApiHeaders = {
    "Accept": "application/vnd.api+json",
    "Content-Type": "application/vnd.api+json",
};

const baseUrl = 'https://kitsu.io/api/edge';

const createRequest = (url) => ({ url, headers: animeApiHeaders });

export const animeApi = createApi({
    reducerPath: 'animeApi',
    baseQuery: fetchBaseQuery({ baseUrl }),
    endpoints: (builder) => ({
        getCategoryOfAnime: builder.query({
            query: (category) =>
                createRequest(`/${category}/anime?limit=20`)
        }),
    })
});

export const { useGetCategoryOfAnimeQuery } = animeApi;

categoriesApi.js (the query that SHOULD be getting called):

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

const categoryHeaders = {
    "Accept": "application/vnd.api+json",
    "Content-Type": "application/vnd.api+json",
};

const baseUrl = 'https://kitsu.io/api/edge';

const createRequest = (url) => ({ url, headers: categoryHeaders });

export const categoriesApi = createApi({
    reducerPath: 'categoriesApi',
    baseQuery: fetchBaseQuery({ baseUrl }),
    endpoints: (builder) => ({
        getAllCategories: builder.query({
            query: () => 
                createRequest(`/categories?page%5Blimit%5D=40`)
        }),
        getThisCategory: builder.query({
            query: (genre) =>
                createRequest(`/anime?filter%5Bcategories%5D=${genre}`)
        }),
    })
});

export const { useGetAllCategoriesQuery, useGetThisCategoryQuery } = categoriesApi;

GenrePage.js (only the relevant parts of component):

import React, { useState, useEffect } from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { Link, useParams } from 'react-router-dom';
import { useGetThisCategoryQuery } from '../../services/categoriesApi';
import { addThisCategory } from './GenrePageSlice';
import CircularProgress from "@mui/material/CircularProgress";
import './GenrePage.css';
import AnimeCard from '../AnimeCard/AnimeCard';

const GenrePage = () => {
    
    const { genre } = useParams();
    const dispatch = useDispatch();
    const genreData = useSelector((state) => state.genrePage.thisCategory);
    const { data: thisCategory, isFetching } = useGetThisCategoryQuery(genre);

    useEffect(() => {
        dispatch(addThisCategory(thisCategory));
    }, [thisCategory]);

store.js:

import { combineReducers, configureStore } from "@reduxjs/toolkit";

import { animeApi } from "../services/animeApi";
import { categoriesApi } from "../services/categoriesApi";

import animeBannerReducer from '../components/AnimeBanner/AnimeBannerSlice';
import animeCategoryReducer from "../components/AnimeCategoryPage/AnimeCategoryPageSlice";
import categoriesReducer from '../components/Categories/CategoriesSlice';

export default configureStore({
    reducer: {
        [animeApi.reducerPath]: animeApi.reducer,
        [categoriesApi.reducerPath]: categoriesApi.reducer,
        animeBanner: animeBannerReducer,
        animeCategory: animeCategoryReducer,
        categories: categoriesReducer,
    },
    middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware().concat(animeApi.middleware, categoriesApi.middleware),
});

App.js:

import React, { useState } from 'react';
import { BrowserRouter, Routes, Route, Link } from 'react-router-dom';

import "./App.css"

import Header from '../components/Header/Header';
import Homepage from '../components/Homepage/Homepage';
import AnimeCategoryPage from '../components/AnimeCategoryPage/AnimeCategoryPage';
import GenrePage from '../components/GenrePage/GenrePage';

const App = () => {

  return (
    <BrowserRouter>
        <div className="app">
          <Header />
          <Routes>
            <Route path="/" element={<Homepage />} />
            <Route path="/anime/:category" element={<AnimeCategoryPage />} />
            <Route path="/anime/:genre" element={<GenrePage />} />
          </Routes>
        </div>
    </BrowserRouter>

  );
};

export default App;


Solution

  • Figured it out - I was being stupid.

    The issue was with my routes set up in App.js.

    Because the GenrePage was being called on the route '/anime/:genre', and the AnimeCategoryPage was being called on '/anime/:category', react-router was always calling the first component on the base '/anime' which was AnimeCategoryPage instead of GenrePage.

    Fixed by changing the route for GenrePage to '/explore/:genre'