与下面类似,我也有一个自定义挂钩:
import { useEffect, useState } from 'react';
import axios from 'axios';
const myCustomHook = () => {
const [countries, setCountries] = useState([]);
const [isLoading, setLoading] = useState(true);
useEffect(() => {
(async () =>
await axios
.get("MY_API/countries")
.then(response => setCountries(response.data))
.finally(() => setLoading(false)))();
}, []);
return countries;
};
export default myCustomHook;
该钩子很好用,尽管我在使用钩子的所有国家/地区都一样,但是我在应用程序的三个不同区域中都使用了它。
是否有一个好的模式可以仅一次而不是三次调用axios请求?
编辑-解决方案后的最终代码
import { useEffect, useState } from 'react';
import axios from 'axios';
let fakeCache = {
alreadyCalled: false,
countries: []
};
const myCustomHook = (forceUpdate = false) => {
const [isLoading, setLoading] = useState(true);
if (!fakeCache.alreadyCalled || forceUpdate) {
fakeCache.alreadyCalled = true;
(async () =>
await axios
.get("MY_API/countries")
.then(response => setCountries(response.data))
.finally(() => setLoading(false)))();
}
return countries;
};
export default myCustomHook;
答案 0 :(得分:1)
一种解决方案是引入一个自定义的“缓存层”(在您的钩子和axios请求之间):
coutries
数据,并且有多种方法可以实现-一种可能性是定义一个getCountries()
函数,该函数在单独的模块中实现该缓存逻辑,然后从钩子中调用该函数:
countries.js
import axios from 'axios';
// Module scoped variable that holds caches data
let cachedData = undefined;
// Example function wraps network request with caching layer
export const getCountries = async() => {
// We expect the data for countries to be an array. If cachedData
// is not an array, attempt to populate the cache with data
if (!Array.isArray(cachedData)) {
const response = await axios.get("MY_API/countries");
// Populate the cache with data returned from request
cachedData = response.data;
}
return cachedData;
}
myCustomHook.js
import { useEffect, useState } from 'react';
import { getCountries } from "/countries";
const myCustomHook = () => {
const [countries, setCountries] = useState([]);
const [isLoading, setLoading] = useState(true);
useEffect(() => {
(async() => {
try {
setLoading(true);
// Update hooks state with countries data (cached or fresh)
setCountries(await getCountries());
} finally {
setLoading(false)
}
}, []);
});
}
export default myCustomHook;
答案 1 :(得分:0)
该组件的每个实例彼此独立运行。
即使第一个实例状态填充了countries
,第二个实例也不知道,并且仍然为空。
您可以改为使用countries
作为道具,如果为空则调用效果,否则只需从道具返回countries
。