skip to Main Content
const [state, setState] = useState({Items : [{
                                        id: 1,
                                        amount: 1,
                                    },
                                    {
                                        id: 2,
                                        amount: 1,
                                    },
                                    {
                                        id: 3,
                                        amount: 1,
                                    },
                                    {
                                        id: 4,
                                        amount: 1,
                                    },],

                                  totalItems :  (function () {
                                    let total = 0;
                                   for (let x of this.Items){
                                    total += x.amount
                                   }
                                   return total
                                  })()
                                });

I want to initialize the state’s ‘totalItems’ property by calculating the total amount of items depending upon the ‘Items’ property of the same object. I had tried this function but it doesnt work. Throws error: Uncaught TypeError: Cannot read properties of undefined (reading ‘Items’).

Can someone explain me why this error occured, as well as the solution to my problem?

2

Answers


  1. The reason that the error occurred, is that you cannot access Items using this default function. Instead, if you use the new ECMAScript 2015 get syntax, you can implement the functionality you require.

    const [state, setState] = useState({
      Items: [
        {
          id: 1,
          amount: 1,
        },
        {
          id: 2,
          amount: 1,
        },
        {
          id: 3,
          amount: 1,
        },
        {
          id: 4,
          amount: 1,
        },
      ],
    
      get totalItems() {
        let total = 0;
        for (let x of this.Items) {
          total += x.amount;
        }
        return total;
      },
    });
    

    You can now access this value as usual, using state.totalItems.

    Login or Signup to reply.
  2. Make the business logic outside of the initial state.

    Create an object and call the function like const yourObj = yourFn(). Then simply set the state with yourObj like const [state, setState] = useState(yourObj). States should be just simple values to store, not values depending on some calculator functions and not complex structures.

    I’m assuming your state’s dependency is not limited with initial phase and will depend on other state. So you can consider about using useEffect depends on your other state. With this way you can make them sync. Like;

    useEffect(()=>{
       const yourObj = yourFn();
       setState(yourObj);
    },[yourOtherState])
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search