优化React性能:使用useMemo或useCallback通过Axios GET Request记住功能?

时间:2020-09-30 18:07:58

标签: javascript reactjs react-native react-hooks

我的目标:

我有一个称为getUnitedStatesCases的相当大的函数,它在其中构成一个Axios GET 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;
}, []);

函数(getUnitedStatesCases):

  // 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();
  }, []);

1 个答案:

答案 0 :(得分:0)

你想做什么对我来说没有意义。
您只需使用useEffect即可完成您要进行的优化。
如果只想一次调用API并对结果进行计算,就可以使用useEffect的数组依赖项控制它。
根据文档:

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

现在,仅当props.source更改时,才会重新创建订阅。
进一步了解here
让我知道您是否还有任何问题