优化React性能:使用useMemo或useCallback使用Axios GET Request实现Memoize功



我的目标:

我有一个相当大的函数,名为getUnitedStatesCases,它生成AxiosGET Request,并对这些数据执行多项操作。我目前在组件安装上的useEffect挂钩中有它,但我如何使用useMemo来记忆该函数?

想法

  1. 我有很多这样的函数(大约20-30(,比如下面的函数,它们的结构非常相似
  2. getUnitedStatesCases需要返回datescasesnewCasesprojectedCases。用useMemo解构有可能吗?例如,以下方法可行吗

非结构化useMemo

const { cases, newCases } useMemo(() => {
// API REQUEST

const responseObject = {
cases: 7000000,
newCases: 5000,
};
return responseObject;
}, []);

函数(getUnitedStatesCase(:

// United States Cases (Timeline)
useEffect(() => {
// Get United States Cases (Timeline)
const getUnitedStatesCases = async () => {
try {
// Axios: CDC API
const response = await axios.get('https://services9.arcgis.com/6Hv9AANartyT7fJW/arcgis/rest/services/USCounties_cases_V1/FeatureServer/1/query?f=json&where=1%3D1&returnGeometry=false&spatialRel=esriSpatialRelIntersects&outFields=*&groupByFieldsForStatistics=dt&orderByFields=dt%20asc&outStatistics=%5B%7B%22statisticType%22%3A%22sum%22%2C%22onStatisticField%22%3A%22Confirmed%22%2C%22outStatisticFieldName%22%3A%22value%22%7D%5D&outSR=102100&resultType=standard&cacheHint=true');
// Current United States Totals
let currentUnitedStatesCasesTotal = 0;
// Current United States Increases
let currentUnitedStatesCasesIncrease = 0;
// Current Dates
let currentCasesDate = null;
// Assign Cases
currentUnitedStatesCasesTotal = response.data.features[response.data.features.length - 1].attributes.value;
// Assign Cases Increase
currentUnitedStatesCasesIncrease = response.data.features[response.data.features.length - 1].attributes.value - response.data.features[response.data.features.length - 2].attributes.value;
// Assign Date
currentCasesDate = new Date(response.data.features[response.data.features.length - 1].attributes.dt);
// Set United States Cases Totals
setUnitedStatesCasesTotal(currentUnitedStatesCasesTotal);
// Set United States Increases
setUnitedStatesCasesIncrease(currentUnitedStatesCasesIncrease);
// All Cases Data + Dates
let allCasesData = [];
let allCasesDates = [];
// All Cases Projected Data + Dates
let allCasesProjectedData = [];
// All New Cases Data + Dates
let allNewCasesData = [];
let allNewCasesDates = [];
// All New Cases Projected Data + Dates
let allNewCasesProjectedData = [];
// Iterate Over API Data
for (let i = 0; i < response.data.features.length; i++) {
// Check If Data Exists
if (response.data.features.length >= 1) {
// Add To Cases Data
allCasesData.push(response.data.features[i].attributes.value);
// Add To Cases Projected Data
allCasesProjectedData.push(null);
// Finish 1 Before The Last Item Due To i + 1
if (i < response.data.features.length - 1) {
// Add To New Cases Data
allNewCasesData.push(response.data.features[i + 1].attributes.value - response.data.features[i].attributes.value);
// Add To New Cases Projected Data
allNewCasesProjectedData.push(null);
}
// Date Options
let dateOptions = {
day: 'numeric',
month: 'numeric',
timeZone: 'UTC',
};
// Formatted Date
let formattedDate = new Date(response.data.features[i].attributes.dt).toLocaleDateString('en-US', dateOptions);
// Add To Cases Dates
allCasesDates.push(formattedDate);
// Add To New Cases Dates
allNewCasesDates.push(formattedDate);
}
}
// Set United States Cases + Dates
setUnitedStatesCasesData(allCasesData);
// See Below For Dates
// Set United States New Cases + Dates
setUnitedStatesNewCasesData(allNewCasesData);
// See Below For Dates
// CASES PROJECTIONS
// Cases Last Date
let casesLastDate = new Date(currentCasesDate);
// Cases Projected First Date (Add 1 Day To Last Date)
let casesProjectedFirstDate = casesLastDate.setDate(casesLastDate.getDate() + 1);
// Current Cases
const currentCases = allCasesData[allCasesData.length - 1];
// Past Cases
const cases2DaysAgo = allCasesData[allCasesData.length - 2];
const cases3DaysAgo = allCasesData[allCasesData.length - 3];
const cases4DaysAgo = allCasesData[allCasesData.length - 4];
const cases5DaysAgo = allCasesData[allCasesData.length - 5];
const cases6DaysAgo = allCasesData[allCasesData.length - 6];
const cases7DaysAgo = allCasesData[allCasesData.length - 7];
const cases8DaysAgo = allCasesData[allCasesData.length - 8];
const cases9DaysAgo = allCasesData[allCasesData.length - 9];
// Day Changes
const casesChange3To2 = (cases2DaysAgo - cases3DaysAgo);
const casesChange4To3 = (cases3DaysAgo - cases4DaysAgo);
const casesChange5To4 = (cases4DaysAgo - cases5DaysAgo);
const casesChange6To5 = (cases5DaysAgo - cases6DaysAgo);
const casesChange7To6 = (cases6DaysAgo - cases7DaysAgo);
const casesChange8To7 = (cases7DaysAgo - cases8DaysAgo);
const casesChange9To8 = (cases8DaysAgo - cases9DaysAgo);
// Daily Cases Change (7 Day Average)
const dailyCasesChange7DayAverage = (casesChange3To2 + casesChange4To3 + casesChange5To4 + casesChange6To5 + casesChange7To6 + casesChange8To7 + casesChange9To8) / 7;
// Generate Projected Cases & Dates For Next 7 Days
let i = 1;
while (i <= 7) {
// Increase Date By 1
casesLastDate.setDate(casesLastDate.getDate() + i);
// Formatted Date
let formattedDate = removeZeros(casesLastDate.toLocaleDateString()).slice(0, 5);
// Add Date To All Dates
allCasesDates.push(formattedDate);
// Increase Daily Amount
let increasedDailyAmount = dailyCasesChange7DayAverage * i;
// Today's Increase
let todaysIncrease = (currentCases + increasedDailyAmount).toFixed(0);
// Convert To Number
todaysIncrease = Number(todaysIncrease);
// Add Cases To Total Projected
allCasesProjectedData.push(todaysIncrease);
// Increase i
i += 1;
// Reset Date
casesLastDate = new Date(casesProjectedFirstDate);
}

// NEW CASES PROJECTIONS
// New Cases Last Date
let newCasesLastDate = new Date(currentCasesDate);
// New Cases Projected First Date (Add 1 Day To Last Date)
let newCasesProjectedFirstDate = newCasesLastDate.setDate(newCasesLastDate.getDate() + 1);
// Current New Cases
const currentNewCases = allNewCasesData[allNewCasesData.length - 1];
// Past New Cases
const newCases2DaysAgo = allNewCasesData[allNewCasesData.length - 2];
const newCases3DaysAgo = allNewCasesData[allNewCasesData.length - 3];
const newCases4DaysAgo = allNewCasesData[allNewCasesData.length - 4];
const newCases5DaysAgo = allNewCasesData[allNewCasesData.length - 5];
const newCases6DaysAgo = allNewCasesData[allNewCasesData.length - 6];
const newCases7DaysAgo = allNewCasesData[allNewCasesData.length - 7];
const newCases8DaysAgo = allNewCasesData[allNewCasesData.length - 8];
const newCases9DaysAgo = allNewCasesData[allNewCasesData.length - 9];
// Day Changes
const newCasesChange3To2 = (newCases2DaysAgo - newCases3DaysAgo);
const newCasesChange4To3 = (newCases3DaysAgo - newCases4DaysAgo);
const newCasesChange5To4 = (newCases4DaysAgo - newCases5DaysAgo);
const newCasesChange6To5 = (newCases5DaysAgo - newCases6DaysAgo);
const newCasesChange7To6 = (newCases6DaysAgo - newCases7DaysAgo);
const newCasesChange8To7 = (newCases7DaysAgo - newCases8DaysAgo);
const newCasesChange9To8 = (newCases8DaysAgo - newCases9DaysAgo);
// Daily New Cases Change (7 Day Average)
const dailyNewCasesChange7DayAverage = (newCasesChange3To2 + newCasesChange4To3 + newCasesChange5To4 + newCasesChange6To5 + newCasesChange7To6 + newCasesChange8To7 + newCasesChange9To8) / 7;
// Generate Projected Cases & Dates For Next 7 Days
let j = 1;
while (j <= 7) {
// Increase Date By 1
newCasesLastDate.setDate(newCasesLastDate.getDate() + j);
// Formatted Date
let formattedDate = removeZeros(newCasesLastDate.toLocaleDateString()).slice(0, 5);
// Add Date To All Dates
allNewCasesDates.push(formattedDate);
// Increase Daily Amount
let increasedDailyAmount = dailyNewCasesChange7DayAverage * j;
// Today's Increase
let todaysIncrease = (currentNewCases + increasedDailyAmount).toFixed(0);
// Convert To Number
todaysIncrease = Number(todaysIncrease);
// Add New Cases To Total Projected
allNewCasesProjectedData.push(todaysIncrease);
// Increase j
j += 1;
// Reset Date
newCasesLastDate = new Date(newCasesProjectedFirstDate);
}
// Set United States Cases Dates
setUnitedStatesCasesDates(allCasesDates);
// Set United States Cases Projected
setUnitedStatesCasesProjectedData(allCasesProjectedData);
// Set United States New Cases Dates (Remove First Element Due To Day To Day Increase/Decrease)
setUnitedStatesNewCasesDates(allNewCasesDates.slice(1));
// Set United States New Cases Projected
setUnitedStatesNewCasesProjectedData(allNewCasesProjectedData);
}
catch (error) {
console.log(error);
}
};
// Get United States Cases (Timeline)
getUnitedStatesCases();
}, []);

您想要做的事情对我来说没有意义。
您想要进行的优化可以简单地使用useEffect来完成
如果您希望您的API调用和计算只对结果执行一次,则可以使用useEffect的数组依赖项对其进行控制
根据文档:

useEffect(
() => {
const subscription = props.source.subscribe();
return () => {
subscription.unsubscribe();
};
},
[props.source],
); 

现在,只有在props.source更改时,才会重新创建订阅
在此处了解更多信息
如果还有任何问题,请告诉我

最新更新