代码之家  ›  专栏  ›  技术社区  ›  masoud khanlo

axios实例的React useState问题

  •  1
  • masoud khanlo  · 技术社区  · 6 月前

    我有以下React组件,它的工作原理非常奇怪!里面的一切 useEffect 钩子是正确的(console.log显示了实例的正确值),但调用后 setApiInstance 对于新创建的axios实例 apiInstance 意外地变成了Promise对象,这很不寻常!

    密码笔: https://codesandbox.io/p/sandbox/4j2dzs?file=%2Fsrc%2FApp.tsx%3A15%2C30

    import React, { useEffect, useState } from "react";
    import axios, { AxiosInstance } from "axios";
    
    const MyComponent = ({ appConfig }: { appConfig: { host: string } }) => {
      const [apiInstance, setApiInstance] = useState<AxiosInstance | null>(null);
    
      useEffect(() => {
        const instance = axios.create({
          baseURL: appConfig.host,
        });
    
        console.log("instance", instance);
        setApiInstance(instance);
      }, [appConfig]);
    
      console.log("apiInstance", apiInstance);
      if (!apiInstance) return;
    
      return null;
    };
    export default function App() {
      return <MyComponent appConfig={{ host: "0.0.0.0" }} />;
    }
    
    

    但如果我在中创建axios实例 useState 初始化器方法,它工作得很好!

    const [apiInstance, setApiInstance] = useState<AxiosInstance | null>(() => axios.create({
            baseURL: appConfig.host,
            params: { website_token: appConfig.websiteToken }
        }));
    

    你能帮我弄清楚发生了什么事吗?

    1 回复  |  直到 6 月前
        1
  •  1
  •   Nick Parsons Felix Kling    6 月前

    这是因为在React中 setState() 从中返回的函数 useState() 可以接受充当 state setter function ,即:

    setState(currState => newState);
    

    在你的情况下 instance 哪一个 axios.create() return是一个函数,因此当你将其传递给 setApiInstance() .

    你可以通过使用state setter函数并返回你的实例来解决这个问题:

    setApiInstance(() => instance);
    

    但是,我会质疑您是否需要首先将您的实例存储在状态中。这样的东西通常最好存储在 ref ,因为你的UI很可能不需要使用/呈现你的实例:

    const apiInstanceRef = useRef<AxiosInstance>();
    useEffect(() => {
      const instance = axios.create({
        baseURL: appConfig.host,
      });
      apiInstanceRef.current = instance;
    }, [appConfig]);