Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React hooks, set return value of a function to state causes infinite loop

Tags:

Infinite loop on setting state

I have a array of objects testData, which I want to filter through to get another array with results:

  const testData = [
    {
      time: "2020-01-23T13:16:53+01:00",
      amount: "0.010000000000000000",
      txid: "7b1f6aa63910618913c1c1c2902671d2e4f074a8c77ecfd3d16994a05fbf952d"
    },
    {
      time: "2020-01-31T09:09:13+01:00",
      amount: "-0.012739560000000000",
      txid: "7df38cb2d7538f794d725e4c7e68a3e1e7ee6fd570c3575c53776808c0200145"
    },
    {
      time: "2020-01-31T09:09:24+01:00",
      amount: "0.010000000000000000",
      txid: "db47ba29a36bd2343af287bd75f489c2f39d7ce1edcf24176c555233b0e24286"
    }
  ];

Code below works almost good, but I cannot set the return value to a state. When I try to useState in a function it gives me infinite loop.

How can I set state of historyResult() return value, so each time when value changes function will call and give me different results.

import React, { useState, useEffect } from 'react';
    
  const History = () => {
    const [filteredArray, setFilteredArray] = useState();
      
      // values are coming from Formik. When changed, function should run once more.
      const historyResult = values => {
        let tType = values && values.transactionType; // Checking if the value exists, saving transactionType of values and saving it to variable
        // testData is an array of objects that I want to filter through
        let filteredData = testData.filter(item => {
          const withdraw = item.amount < 0;
          const admission = item.amount > 0;
          // Checking which tType was returned and do instructions
          const type = tType == 1 ? withdraw : tType == 2 ? admission : console.log('no value');
          return type;
        });
        console.log(filteredData); // This log works beautifully - it gives me data I want (array of objects)
        setFilteredArray(filteredData); // I tried to set state on this but got infinite loop. Why's that?
        return filteredData;
      };
  }
     
  1. How can I set return value of historyResult to a state without infinite loop?
  2. I tried useEffect but I think I got it all wrong and also got infinite loop.
like image 553
Navian Avatar asked Feb 11 '20 09:02

Navian


1 Answers

  1. You can use:

setFilteredArray([...filteredData]);

Also initialize your state with initial value for e.g. empty array

const [filteredArray, setFilteredArray] = useState([]);

You don't need to return a value from function. You never do it in the React world, instead you just set your state with the desired results and use that state where you want. (keep in mind that setting state is an async call)

  1. Reason for infinite loop in useEffect:

useEffect calls every time the component state changes and whenever state changes again useEffect gets call and this cycle continues. Here is good guide to prevent infinite loop in the useEffect

like image 187
Zain Ul Abideen Avatar answered Oct 05 '22 20:10

Zain Ul Abideen