Reputation: 1584
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
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
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
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