代码之家  ›  专栏  ›  技术社区  ›  poltergaz

无法在上下文提供程序内发出axios请求

  •  0
  • poltergaz  · 技术社区  · 2 年前

    我正试图用 axios react-query 可用于我的组件 Context API 但是 axios.get() 似乎不起作用。我不明白 GET 服务器端的请求和axios返回的数据是 undefined .

    kitDataContext.js

    在这里,我试图 console.log() 返回的数据 axios.get() 它可以打印 未定义 在控制台上:

    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

    这是我目前将使用数据的唯一组件,我还没有对数据进行任何处理,只是到目前为止为组件提供了上下文。请注意,我还用所需的提供者包装了这个组件,这样我就可以简化在 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

    在这里,我只是渲染组件:

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

    /kitsDB路线

    这是的服务器路由 /kitsDB ,它打印” request! “当我用浏览器访问它时,而不是当我运行上面显示的脚本时:

    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!");
    });
    

    我试着用 axios.get() 在同一条路线上的上下文之外,一切都很好,所以问题一定是我使用上下文的方式。我是React的新手,我看不出到底出了什么问题。我谦卑地请求你能给我的任何帮助。

    0 回复  |  直到 2 年前
        1
  •  1
  •   ontanj    2 年前

    不允许放置钩子(如 useQuery )内部自定义函数(例如 RQKitsDB ),它需要放置在组件的顶层。

    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>
        );  
    };
    

    现在 data 可以这样访问

    const { data } = useContext(kitsDataContext);
    
        2
  •  0
  •   poltergaz    2 年前
    const { isLoading, data } = useQuery(["kitsDB"], () => fetchKits());
    

    我修复了更改useQuery行的问题。我想是什么让它起作用的 fetchKits() 而不是仅仅把它当作 fetchKits 不知道为什么,因为我遇到的每个人都建议在将函数作为参数传递时不要调用它们,但好吧,如果它有效,它也有效。