user14265379
user14265379

Reputation:

Calculate sum of values in state with React Hooks

I'm using React Hooks to store datas in the state. I would like to create a function that calculate the sum of the values. I tried something but it is not working.

Here is my component with the function "totalIncome" :

import { UidContext } from "../components/AppContext"
import React, { useContext, useEffect, useState } from "react"
import axios from "axios"

export default function Balance() {
    const uid = useContext(UidContext)
    const [userWalletIncomes, setUserWalletIncomes] = useState('')
    const [userWalletFees, setUserWalletFees] = useState('')
    const [formIncomes, setformIncomes] = useState(false)

    useEffect(() => {
        if (uid !== null) {
            axios.get(`${process.env.REACT_APP_API_URL}api/balance/${uid}`)
                .then((res) => {
                    setUserWalletIncomes(res.data[0].incomes)
                    setUserWalletFees(res.data[0].fees)
                })
        }
    }, [uid])

    const totalIncome = () => {
        Object.entries(userWalletIncomes).map(([key, value]) => {
            let total = 0
            console.log(value)
            for (let i = 0; i < value.length; i++) {
                total += value[i]
            }
            return total
        })
    }

    return (
            <section className="border my-2 w-max md:w-11/12 mx-auto text-center">
                <h1 className="text-3xl my-5">Solde</h1>
                <div className="text-left mx-auto flex">
                    <p className="w-32 border p-1">Montant des revenus</p>
                    <p className="w-32 border p-1">{totalIncome()}</p>
                </div>
            </section>
    )
}

The console.log(value) returns :

1500 Balance.js:42 
640 Balance.js:42 
90 Balance.js:42 
1500 Balance.js:42 
640 Balance.js:42 
90 Balance.js:42

Any idea ? Thank you

Upvotes: 2

Views: 7734

Answers (2)

dave
dave

Reputation: 64657

From what your logs are showing, I'd expect the function to work like this:

const totalIncome = () => {
    let total = 0
    Object.entries(userWalletIncomes).forEach(([key, value]) => {
        total += value
    })
    return total
}

Upvotes: 1

Drew Reese
Drew Reese

Reputation: 202882

It seems you are close. You are logging the value and it's clearly not an array, so there is no length property and you can't iterate over it.

I would suggest using an array.reduce over the object's values and sum them with a computed total.

const totalIncome = () => {
  return Object.values(userWalletIncomes).reduce((total, value) => total + value, 0)
}

Other than this, you need to provide valid initial state for userWalletIncomes, i.e. it needs to be an object instead of an empty string. This is so the totalIncome function can work correctly with the initial state until the data is fetched and/or updated.

const [userWalletIncomes, setUserWalletIncomes] = useState({});

Upvotes: 5

Related Questions