skip to Main Content

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.

2

Answers


  1. Chosen as BEST ANSWER
    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.


  2. You are not allowed to put hooks (such as useQuery) inside custom functions (such as RQKitsDB), it needs to be placed in the top level of the component.

    export const KitsDataProvider = ({children}) => {
    
        const fetchKits = () =>{
            return axios.get("http://localhost:5001/kitsDB");
        };
        
        // put useQuery in top level of component
        const { isLoading, data } = useQuery("kitsDB", fetchKits);
    
        return( 
            <kitsDataContext.Provider value={{data}}>
                {children}
            </kitsDataContext.Provider>
        );  
    };
    

    Now data can be accessed like this

    const { data } = useContext(kitsDataContext);
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search