Search code examples
javascriptreactjsreact-contextreact-query

Can't make axios request inside context provider


I am trying to make the data fetched with axios and react-query available to my components using Context API, but axios.get() doesn't seem to work. I get no GET request on the server-side and the data returned by axios is undefined.

kitDataContext.js

Here I tried to console.log() the data returned by axios.get() and it prints undefined on the console:

import { useQuery } from '@tanstack/react-query'
import axios from 'axios'
import { createContext } from 'react';

export const kitsDataContext = createContext();

//creates provider so content on the DB can be accessible to all components
export const KitsDataProvider = ({children}) => {

    const fetchKits = () =>{
        return axios.get("http://localhost:5001/kitsDB");
    };

    //saves JSON data on "data" variable
    function RQKitsDB(){
        const { isLoading, data } = useQuery("kitsDB", fetchKits);

        //prints undefined...
        console.log(data);
        return { data };
    };

    return( 
        <kitsDataContext.Provider value={{RQKitsDB}}>
            {children}
        </kitsDataContext.Provider>
    );  
};

SerumRow.js

This is the only component I'll be using the data for now, I didn't make anything with the data yet, just made the context available for the component so far. Note that I am also wrapping this component with the required providers so I can simplify my rendering on index.js.

import "./row.css"
import {Button} from 'react-bootstrap';
import AddToCart from './AddToCart.js';

import { useContext } from 'react';
import { kitsDataContext } from './contexts/kitsDataContext.js'

import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { KitsDataProvider } from './contexts/kitsDataContext.js'

const queryClient = new QueryClient()

//complete row with all the data from database, also adds AddToCart button below every kit
function SerumRowNoProviders() {

  const { RQKitsDB } = useContext(kitsDataContext);
  const { data } = RQKitsDB;

  return (
    
      <div className="small-container">
        <h1>SERUM PRESETS</h1>
        <div className="row">
          <div className="col-3 text-center">
            <img src="./images/WavSupply-Sidepce-Elysium-Loop-Kit-920x920.jpg" alt="Product 1" />
            <div></div>
            <div className="priceReact"></div>
            <AddToCart />
          </div>
          <div className="col-3 text-center">
            <img src="./images/WavSupply-Sidepce-Elysium-Loop-Kit-920x920.jpg" alt="Product 2" />
            <div></div>
            <div className="priceReact"></div>
            <AddToCart />
          </div>
          <div className="col-3 text-center">
            <img src="./images/WavSupply-Sidepce-Elysium-Loop-Kit-920x920.jpg" alt="Product 3" />
            <div></div>
            <div className="priceReact"></div>
            <AddToCart />
          </div>
          <div className="col-3 text-center">
            <img src="./images/WavSupply-Sidepce-Elysium-Loop-Kit-920x920.jpg" alt="Product 4" />
            <div></div>
            <div className="priceReact"></div>
            <AddToCart />
          </div>
        </div>
        {/*takes user to page with all avaliable kits */}
        <h1><button type="button" id="show-more" className="btn btn-outline-dark btn-lg">BROWSE ALL</button></h1>
      </div>
  );
}

//wraps SerumRowNoProviders() with needed Providers
function SerumRow() {
  return (
    <QueryClientProvider client={queryClient}>
      <KitsDataProvider>
        <SerumRowNoProviders />
      </KitsDataProvider>
    </QueryClientProvider>
  );
}

export default SerumRow;

index.js

Here I am simply rendering the component:

const serumRow = document.getElementById("SerumRow");
root = ReactDOM.createRoot(serumRow);
root.render(
  <React.StrictMode>
        <SerumRow />
  </React.StrictMode>
  );

/kitsDB route

This is the server route for /kitsDB, it prints "request!" when I access it with the browser but not when I run the script I showed above:

app.get("/kitsDB", async (req,res) => {
    //returns all kits from DB organized by newest first
    const result = await Kits.find().sort({_id:-1});
    res.send({"aa" : result});
    console.log("request!");
});

I tried using axios.get() outside of the context on that same route and everything worked fine, so the issue must be the way I am using context. I am quite new to React and I can't see exactly what is wrong. I humbly ask for any help you can give me.


Solution

  • const { isLoading, data } = useQuery(["kitsDB"], () => fetchKits());
    

    I fixed the problem changing that useQuery line. I think what made it work was evoking fetchKits() instead of just passing it as fetchKits. Not sure why since everybody I came across suggested not evoking functions when passing them as arguments but well, if it works, it works.