组件使用自定义 axios 挂钩不断进行 api 次调用
Component keeps making api calls with custom axios hook
我有一个显示一些小部件的仪表板组件。它从四个不同的 API 中获取小部件数据。
Dashbaord.jsx
import { Box, Stack } from '@mui/material';
import { useAxios } from '../../api/use-axios';
import { NewWidget } from '../../components/widget/NewWidget';
import ApiConfig from '../../api/api-config';
const Dashboard = () => {
const { response: studentResponse } = useAxios({
url: ApiConfig.STUDENTS.base,
});
const { response: courseResponse } = useAxios({
url: ApiConfig.COURSES.base,
});
const { response: feesResponse } = useAxios({
url: ApiConfig.FEES.total,
});
return (
<Box padding={2} width="100%">
<Stack direction={'row'} justifyContent="space-between" gap={2} mb={10}>
<NewWidget type={'student'} counter={studentResponse?.data?.length} />
<NewWidget type={'course'} counter={courseResponse?.data?.length} />
<NewWidget type={'earning'} counter={feesResponse?.data} />
<NewWidget type={'teacher'} counter={studentResponse?.data?.length} />
</Stack>
</Box>
);
};
export default Dashboard;
它使用自定义挂钩 useAxios
进行 API 调用。
使用-axios.jsx
import { useState, useEffect } from 'react';
import axios from 'axios';
axios.defaults.baseURL = 'http://localhost:3000';
export const useAxios = (axiosParams) => {
const [response, setResponse] = useState(undefined);
const [error, setError] = useState('');
const [loading, setLoading] = useState(true);
const fetchData = async (params) => {
try {
const result = await axios.request({
...params,
method: params.method || 'GET',
baseURL: 'http://localhost:3000',
headers: {
accept: 'application/json',
},
});
setResponse(result.data);
} catch (error) {
setError(error);
} finally {
setLoading(false);
}
};
useEffect(() => {
fetchData(axiosParams);
}, [axiosParams]); // execute once only
return { response, error, loading };
};
api-config.js
export default {
COURSES: {
base: '/courses',
},
FEES: {
base: '/fees',
total: '/fees/total',
},
STUDENTS: {
base: '/students',
},
};
但不知何故,它会继续呈现,所有响应也会形成 APIs,它会记录到 undefiend
。
我尝试从 useAxios
中的 useEffect
删除依赖项 axiosPamras
,它停止发出多个请求但仍然显示 dependency warning
并且响应仍然是 undefined
.
更新:
undefined
错误已修复,我没有传递授权令牌。 :(
但是当 axiosParams
添加到依赖项时它仍然在循环中调用 apis
发生这种情况是因为您的呼叫方式 useAxios
。您每次都传递一个对象文字,例如
const { response: studentResponse } = useAxios({
url: ApiConfig.STUDENTS.base,
});
因为您正在调用一个对象,所以 this 的相等性由引用决定 - 传递一个对象文字是每个渲染器上的一个新引用,即使它是您所关注的“相同”对象.因此,以 axiosParams
作为其依赖项的 useEffect
每次都会重新运行,因此会重复发送请求。
在这种情况下,最简单的解决方案可能是将这些对象提取为存储在组件外部的常量 - 它们来自 ApiConfig
对象,因此当应用程序 [=30] 时,这似乎不太可能改变=].这样做意味着引用将始终相同,因此不会触发您的 useEffect
重新运行。
也就是把这个放在组件外面:
const STUDENT_AXIOS_CONFIG = { url: ApiConfig.STUDENTS.base };
另外两套axios参数也一样。然后在组件内部做:
const { response: studentResponse } = useAxios(STUDENT_AXIOS_CONFIG);
当然对其他 2 个调用也做同样的事情。
我有一个显示一些小部件的仪表板组件。它从四个不同的 API 中获取小部件数据。
Dashbaord.jsx
import { Box, Stack } from '@mui/material';
import { useAxios } from '../../api/use-axios';
import { NewWidget } from '../../components/widget/NewWidget';
import ApiConfig from '../../api/api-config';
const Dashboard = () => {
const { response: studentResponse } = useAxios({
url: ApiConfig.STUDENTS.base,
});
const { response: courseResponse } = useAxios({
url: ApiConfig.COURSES.base,
});
const { response: feesResponse } = useAxios({
url: ApiConfig.FEES.total,
});
return (
<Box padding={2} width="100%">
<Stack direction={'row'} justifyContent="space-between" gap={2} mb={10}>
<NewWidget type={'student'} counter={studentResponse?.data?.length} />
<NewWidget type={'course'} counter={courseResponse?.data?.length} />
<NewWidget type={'earning'} counter={feesResponse?.data} />
<NewWidget type={'teacher'} counter={studentResponse?.data?.length} />
</Stack>
</Box>
);
};
export default Dashboard;
它使用自定义挂钩 useAxios
进行 API 调用。
使用-axios.jsx
import { useState, useEffect } from 'react';
import axios from 'axios';
axios.defaults.baseURL = 'http://localhost:3000';
export const useAxios = (axiosParams) => {
const [response, setResponse] = useState(undefined);
const [error, setError] = useState('');
const [loading, setLoading] = useState(true);
const fetchData = async (params) => {
try {
const result = await axios.request({
...params,
method: params.method || 'GET',
baseURL: 'http://localhost:3000',
headers: {
accept: 'application/json',
},
});
setResponse(result.data);
} catch (error) {
setError(error);
} finally {
setLoading(false);
}
};
useEffect(() => {
fetchData(axiosParams);
}, [axiosParams]); // execute once only
return { response, error, loading };
};
api-config.js
export default {
COURSES: {
base: '/courses',
},
FEES: {
base: '/fees',
total: '/fees/total',
},
STUDENTS: {
base: '/students',
},
};
但不知何故,它会继续呈现,所有响应也会形成 APIs,它会记录到 undefiend
。
我尝试从 useAxios
中的 useEffect
删除依赖项 axiosPamras
,它停止发出多个请求但仍然显示 dependency warning
并且响应仍然是 undefined
.
更新:
undefined
错误已修复,我没有传递授权令牌。 :(
但是当 axiosParams
添加到依赖项时它仍然在循环中调用 apis
发生这种情况是因为您的呼叫方式 useAxios
。您每次都传递一个对象文字,例如
const { response: studentResponse } = useAxios({
url: ApiConfig.STUDENTS.base,
});
因为您正在调用一个对象,所以 this 的相等性由引用决定 - 传递一个对象文字是每个渲染器上的一个新引用,即使它是您所关注的“相同”对象.因此,以 axiosParams
作为其依赖项的 useEffect
每次都会重新运行,因此会重复发送请求。
在这种情况下,最简单的解决方案可能是将这些对象提取为存储在组件外部的常量 - 它们来自 ApiConfig
对象,因此当应用程序 [=30] 时,这似乎不太可能改变=].这样做意味着引用将始终相同,因此不会触发您的 useEffect
重新运行。
也就是把这个放在组件外面:
const STUDENT_AXIOS_CONFIG = { url: ApiConfig.STUDENTS.base };
另外两套axios参数也一样。然后在组件内部做:
const { response: studentResponse } = useAxios(STUDENT_AXIOS_CONFIG);
当然对其他 2 个调用也做同样的事情。