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
I fixed the problem changing that useQuery line. I think what made it work was evoking
fetchKits()
instead of just passing it asfetchKits
. Not sure why since everybody I came across suggested not evoking functions when passing them as arguments but well, if it works, it works.You are not allowed to put hooks (such as
useQuery
) inside custom functions (such asRQKitsDB
), it needs to be placed in the top level of the component.Now
data
can be accessed like this