AMendis
AMendis

Reputation: 1584

Using usestate hook with array when getting data from redux store

I'm getting my family from store like below from very top

const family:Family = useSelector((state:any) => state.family.family);

This is my family object

address: "No 48, Katukurunda"
enabled: true
id: 1
members: Array(2)
0: {id: "5", first_name: "Rohan", last_name: "Perera"}
1: {id: "4", first_name: "Sohani", last_name: "Perera"}
length: 2
__proto__: Array(0)
monthly_contribution: 50
name: "Mendis Family

as you can see clearly members have 2 items

So I have a UseState item to calculate row numbers like this

const [rowNumber, setRowNumber] = useState<number[]>([]);

I have a useEffect on top to setRowNumber like this

useEffect(() => {
    if (family) {
      family.members.forEach(() => {
        setRowNumber([...rowNumber, rowNumber.length + 1]);
      });
    }
  }, [family, setRowNumber]);

Just to check how many rows available when page loading I have added this code

  useEffect(() => {
    console.log(rowNumber);
  }, [rowNumber]);

but above console log shows me this [1], an array with only one item. What happened to the second member ?

I use rowNumber.map() to show available members of that Family. But when page loads it shows only one text box which is correct according to below useEffect

useEffect(() => {
        console.log(rowNumber);
      }, [rowNumber]);

What am I doing wrong here ? Why rowNumber has only ONE item ?

family.members clearly has 2 items

I just realized only last value contains in rowNumber array

Upvotes: 1

Views: 1285

Answers (3)

user13503900
user13503900

Reputation: 125

Content inside useEffect is wrong for storing array inside useState.

Use below code,

 useEffect(() => {
        if (family) {
          family.members.map((item) => {
            setRowNumber(()=> { 
              console.log(item); // verify result with this console log
              return [...rowNumber, rowNumber.length + 1]
             });
          });
        }
      }, [family, setRowNumber]);

Upvotes: -1

Giovanni Esposito
Giovanni Esposito

Reputation: 11176

Could be related to the fact that setRowNumber is async. Have you tried to use a local array? Something like:

useEffect(() => {
    if (family) {
      let result = [];
      family.members.forEach(() => {
        result.push(result.length + 1);
      });
      setRowNumber(result);
    }
  }, [family, setRowNumber]);

Upvotes: 1

Bhuwan Chandra
Bhuwan Chandra

Reputation: 315

Calling setState() in React is asynchronous, this means that setState does not update state immediately, so in the last iteration it will add 0 + 1 in your state. try to do it like this:

 useEffect(() => {
    if (family) {
      const rows = [];
      family.members.forEach((value, i) => {
        rows.push(i + 1);
      });
      setRowNumber(rows);
    }
  }, [family, setRowNumber]);

Upvotes: 1

Related Questions