useState 问题

问题描述 投票:0回答:1

我有以下 React 组件,它的工作方式非常奇怪!

useEffect
钩子内的一切都是正确的(console.log显示了实例的正确值),但是在使用新创建的axios实例调用
setApiInstance
之后,
apiInstance
意外地变成了Promise对象,这是很不寻常的!

Codepen: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" }} />;
}

但是如果我在

useState
初始化方法中创建 axios 实例,它就可以正常工作!

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

你能帮我看看发生了什么事吗?

reactjs react-hooks axios jsx tsx
1个回答
1
投票

这是因为在 React 中,从

setState()
 返回的 
useState()
函数可以接受充当 状态设置器函数的函数,即:

setState(currState => newState);

在你的例子中,

instance
返回的
axios.create()
是一个函数,因此当你将其传递给
setApiInstance()
时,React将其视为状态设置函数。

您可以通过使用状态设置函数并返回实例来解决此问题:

setApiInstance(() => instance);

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

const apiInstanceRef = useRef<AxiosInstance>();
useEffect(() => {
  const instance = axios.create({
    baseURL: appConfig.host,
  });
  apiInstanceRef.current = instance;
}, [appConfig]);
© www.soinside.com 2019 - 2024. All rights reserved.