1

I have this code

import React from 'react';
import { Button, Image, StyleSheet, Text, View } from 'react-native';

function App() {
  const firstCategory = [
    { id: 1, name: 'person1' },
    { id: 2, name: 'person2' },
    { id: 3, name: 'person3' },
    { id: 4, name: 'person4' },
  ];
  const [secondCategory, setSecondCategory] = React.useState([
    { id: 5, name: 'person5' },
    { id: 6, name: 'person6' },
    { id: 7, name: 'person7' },
    { id: 8, name: 'person8' },
  ]);

  React.useEffect(() => {
    setSecondCategory([]);
    for (var i = 0; i < firstCategory.length; i++) {
      setSecondCategory((secondCategoryArray) => [...secondCategoryArray, firstCategory[i]]);
    }
  },[]);



  return (
    <View>
      {secondCategory.map((item) => {
        return <Text>{item.name}</Text>;
      })}
    </View>
  );
}



export default App;

It is supposed to empty the secondCategory array and fill it with firstCategory array but when I console.log secondCategory array I get [undefined,undefined,undefined,undefined] and I get the error message 'cannot read property name of undefined'. I know that there are many other ways to achieve the wanted result but I want to know exactly the cause of this problem in this specific situation.

  • The callback(s) you pass to `setSecondCategory` can be (and apparently are) executed asynchronously, after the loop finishes. – Bergi Sep 20 '21 at 19:39
  • The better practice would be to build your new array in the `for` loop with a temp variable, and then only call `setSecondCategory` once after the loop completes. – Brian Thompson Sep 20 '21 at 19:41
  • @Bergi Can you please explain further – colder programmer Sep 20 '21 at 19:41
  • @BrianThompson can you please explain the cause of the problem – colder programmer Sep 20 '21 at 19:42
  • 1
    The issue is asynchronous nature of updating state, and when `i` is actually evaluated. Your loop expects `i` to have the values 0,1,2,3 as it steps through the loop. However, since you are using `i` within the callback of `setSecondCategory`, `i` is actually evaluated as being 4 one or more times. This is because your callback gets executed **after** the final loop where `i++` has incremented it past your loops condition. – Brian Thompson Sep 20 '21 at 19:48
  • You can test this yourself by adding console logs inside the loop (where it will log 0,1,2,3) and by adding a function body to your state setter and a console log there (`setSecondCategory((p) => {console.log(i); return [...etc];})`) where for me it logged 1,4,4,4 – Brian Thompson Sep 20 '21 at 19:50
  • 1
    From the comments of the linked duplicate, simply using `let` instead of `var` does actually fix the problem you're having – Brian Thompson Sep 20 '21 at 19:54
  • @colderprogrammer Did you read the questions suggested as duplicates? – Bergi Sep 20 '21 at 20:06

0 Answers0